├── .github
└── workflows
│ └── Continuous-integration.yml
├── LICENSE
├── README.md
├── examples
├── VL53L8CX_HelloWorld_I2C
│ └── VL53L8CX_HelloWorld_I2C.ino
├── VL53L8CX_HelloWorld_SPI
│ └── VL53L8CX_HelloWorld_SPI.ino
└── VL53L8CX_ThresholdDetection
│ └── VL53L8CX_ThresholdDetection.ino
├── keywords.txt
├── library.properties
└── src
├── vl53l8cx.cpp
├── vl53l8cx.h
├── vl53l8cx_api.c
├── vl53l8cx_api.h
├── vl53l8cx_buffers.h
├── vl53l8cx_platform.c
├── vl53l8cx_platform.h
├── vl53l8cx_platform_config.h
├── vl53l8cx_platform_config_default.h
├── vl53l8cx_plugin_detection_thresholds.c
├── vl53l8cx_plugin_detection_thresholds.h
├── vl53l8cx_plugin_motion_indicator.c
├── vl53l8cx_plugin_motion_indicator.h
├── vl53l8cx_plugin_xtalk.c
└── vl53l8cx_plugin_xtalk.h
/.github/workflows/Continuous-integration.yml:
--------------------------------------------------------------------------------
1 | name: VL53L8CX Continuous Integration
2 | on:
3 | push:
4 | branches:
5 | - main
6 | paths-ignore:
7 | - '*'
8 | - '**.md'
9 | - '**.txt'
10 | pull_request:
11 | paths-ignore:
12 | - '*'
13 | - '**.md'
14 | - '**.txt'
15 | jobs:
16 | astyle_check:
17 | runs-on: ubuntu-latest
18 | name: AStyle check
19 | steps:
20 | # First of all, clone the repo using the checkout action.
21 | - name: Checkout
22 | uses: actions/checkout@main
23 |
24 | - name: Astyle check
25 | id: Astyle
26 | uses: stm32duino/actions/astyle-check@main
27 |
28 | # Use the output from the `Astyle` step
29 | - name: Astyle Errors
30 | if: failure()
31 | run: |
32 | cat ${{ steps.Astyle.outputs.astyle-result }}
33 | exit 1
34 | codespell:
35 | name: Check for spelling errors
36 | runs-on: ubuntu-latest
37 | steps:
38 | - name: Checkout
39 | uses: actions/checkout@main
40 |
41 | # See: https://github.com/codespell-project/actions-codespell/blob/master/README.md
42 | - name: Spell check
43 | uses: codespell-project/actions-codespell@master
44 | with:
45 | check_filenames: true
46 | check_hidden: true
47 | lib_build:
48 | runs-on: ubuntu-latest
49 | name: Library compilation
50 | steps:
51 |
52 | # First of all, clone the repo using the checkout action.
53 | - name: Checkout
54 | uses: actions/checkout@main
55 |
56 | - name: Compilation
57 | id: compile
58 | uses: stm32duino/actions/compile-examples@main
59 | with:
60 | board-pattern: "NUCLEO_L476RG"
61 |
62 | # Use the output from the `Compilation` step
63 | - name: Compilation Errors
64 | if: failure()
65 | run: |
66 | cat ${{ steps.compile.outputs.compile-result }}
67 | exit 1
68 |
--------------------------------------------------------------------------------
/LICENSE:
--------------------------------------------------------------------------------
1 | BSD 3-Clause License
2 |
3 | Copyright (c) 2024, STM32duino
4 |
5 | Redistribution and use in source and binary forms, with or without
6 | modification, are permitted provided that the following conditions are met:
7 |
8 | 1. Redistributions of source code must retain the above copyright notice, this
9 | list of conditions and the following disclaimer.
10 |
11 | 2. Redistributions in binary form must reproduce the above copyright notice,
12 | this list of conditions and the following disclaimer in the documentation
13 | and/or other materials provided with the distribution.
14 |
15 | 3. Neither the name of the copyright holder nor the names of its
16 | contributors may be used to endorse or promote products derived from
17 | this software without specific prior written permission.
18 |
19 | THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
20 | AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
21 | IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
22 | DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
23 | FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
24 | DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
25 | SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
26 | CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
27 | OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
28 | OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
29 |
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 | # VL53L8CX
2 | Arduino library to support the VL53L8CX Time-of-Flight 8x8 multizone ranging sensor with wide field view.
3 |
4 | ## API
5 |
6 | This sensor uses I2C/SPI to communicate. And I2C/SPI instance is required to access to the sensor.
7 | The APIs provide simple distance measure and multizone detection in both polling and interrupt modes.
8 | The APIs derive from VL53L8CX ULD SDK v1.3.0.
9 |
10 | ## Examples
11 |
12 | The examples contained in this library are based on VL53L8CX-SATEL sensor board.
13 |
14 | You need to connect the VL53L8CX-SATEL sensor board directly to the Nucleo board with wires as explained below in the case of I2C communication:
15 | - pin 1 (SPI_I2C_n) of the VL53L8CX satellite connected to pin GND of the Nucleo board
16 | - pin 2 (LPn) of the VL53L8CX satellite connected to pin A3 of the Nucleo board
17 | - pin 3 (NCS) not connected
18 | - pin 4 (MISO) not connected
19 | - pin 5 (MOSI_SDA) of the VL53L8CX satellite connected to pin D14 (SDA) of the Nucleo board
20 | - pin 6 (MCLK_SCL) of the VL53L8CX satellite connected to pin D15 (SCL) of the Nucleo board
21 | - pin 7 (PWREN) of the VL53L8CX satellite connected to pin D11 of the Nucleo board
22 | - pin 8 (I0VDD) of the VL53L8CX satellite not connected
23 | - pin 9 (3V3) of the VL53L8CX satellite not connected
24 | - pin 10 (1V8) of the VL53L8CX satellite not connected
25 | - pin 11 (5V) of the VL53L8CX satellite connected to 5V of the Nucleo board
26 | - GPIO1 of VL53L8CX satellite connected to A2 pin of the Nucleo board (not used)
27 | - GND of the VL53L8CX satellite connected to GND of the Nucleo board
28 |
29 | You need to connect the VL53L8CX-SATEL sensor board directly to the Nucleo board with wires as explained below in the case of SPI communication:
30 | - pin 1 (SPI_I2C_n) of the VL53L8CX satellite connected to 3V3 of the Nucleo board
31 | - pin 2 (LPn) of the VL53L8CX satellite connected to 3V3 of the Nucleo board
32 | - pin 3 (NCS) of the VL53L8CX satellite connected to pin D10 of the Nucleo board
33 | - pin 4 (MISO) of the VL53L8CX satellite connected to pin D5 of the Nucleo board
34 | - pin 5 (MOSI_SDA) of the VL53L8CX satellite connected to pin D4 (MOSI) of the Nucleo board
35 | - pin 6 (MCLK_SCL) of the VL53L8CX satellite connected to pin D3 (MCLK_SCL) of the Nucleo board
36 | - pin 7 (PWREN) of the VL53L8CX satellite connected to pin D11 of the Nucleo board
37 | - pin 8 (I0VDD) of the VL53L8CX satellite not connected
38 | - pin 9 (3V3) of the VL53L8CX satellite not connected
39 | - pin 10 (1V8) of the VL53L8CX satellite not connected
40 | - pin 11 (5V) of the VL53L8CX satellite connected to 5V of the Nucleo board
41 | - GPIO1 of VL53L8CX satellite connected to A2 pin of the Nucleo board (not used)
42 | - GND of the VL53L8CX satellite connected to GND of the Nucleo board
43 |
44 | There are 3 examples with the VL53L8CX library:
45 |
46 | * VL53L8CX_Sat_HelloWorld_I2C: This example code is to show how to get multizone detection and proximity
47 | values of the VL53L8CX satellite sensor in polling mode using I2C communication.
48 |
49 | * VL53L8CX_Sat_HelloWorld_SPI: This example code is to show how to get multizone detection and proximity
50 | values of the VL53L8CX satellite sensor in polling mode using SPI communication.
51 |
52 | * VL53L8CX_ThresholdsDetection: This example code is to show how to configure the thresholds detection of the VL53L8CX satellite sensor.
53 |
54 |
55 | ## Documentation
56 |
57 | You can find the source files at
58 | https://github.com/stm32duino/VL53L8CX
59 |
60 | The VL53L8CX datasheet is available at
61 | https://www.st.com/en/imaging-and-photonics-solutions/VL53L8CX.html
62 |
--------------------------------------------------------------------------------
/examples/VL53L8CX_HelloWorld_I2C/VL53L8CX_HelloWorld_I2C.ino:
--------------------------------------------------------------------------------
1 | /**
2 | ******************************************************************************
3 | * @file VL53L8CX_HelloWorld_I2C.ino
4 | * @author STMicroelectronics
5 | * @version V2.0.0
6 | * @date 27 June 2024
7 | * @brief Arduino test application for STMicroelectronics VL53L8CX
8 | * proximity sensor satellite based on FlightSense.
9 | * This application makes use of C++ classes obtained from the C
10 | * components' drivers.
11 | ******************************************************************************
12 | * @attention
13 | *
14 | *
© COPYRIGHT(c) 2024 STMicroelectronics
15 | *
16 | * Redistribution and use in source and binary forms, with or without modification,
17 | * are permitted provided that the following conditions are met:
18 | * 1. Redistributions of source code must retain the above copyright notice,
19 | * this list of conditions and the following disclaimer.
20 | * 2. Redistributions in binary form must reproduce the above copyright notice,
21 | * this list of conditions and the following disclaimer in the documentation
22 | * and/or other materials provided with the distribution.
23 | * 3. Neither the name of STMicroelectronics nor the names of its contributors
24 | * may be used to endorse or promote products derived from this software
25 | * without specific prior written permission.
26 | *
27 | * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
28 | * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
29 | * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
30 | * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
31 | * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
32 | * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
33 | * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
34 | * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
35 | * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
36 | * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
37 | *
38 | ******************************************************************************
39 | */
40 | /*
41 | * To use these examples you need to connect the VL53L8CX satellite sensor directly to the Nucleo board with wires as explained below:
42 | * pin 1 (SPI_I2C_N) of the VL53L8CX satellite connected to pin GND of the Nucleo board
43 | * pin 2 (LPn) of the VL53L8CX satellite connected to pin A3 of the Nucleo board
44 | * pin 3 (NCS) not connected
45 | * pin 4 (MISO) not connected
46 | * pin 5 (MOSI_SDA) of the VL53L8CX satellite connected to pin D14 (SDA) of the Nucleo board
47 | * pin 6 (MCLK_SCL) of the VL53L8CX satellite connected to pin D15 (SCL) of the Nucleo board
48 | * pin 7 (PWREN) of the VL53L8CX satellite connected to pin D11 of the Nucleo board
49 | * pin 8 (I0VDD) of the VL53L8CX satellite not connected
50 | * pin 9 (3V3) of the VL53L8CX satellite not connected
51 | * pin 10 (1V8) of the VL53L8CX satellite not connected
52 | * pin 11 (5V) of the VL53L8CX satellite connected to 5V of the Nucleo board
53 | * GPIO1 of VL53L8CX satellite connected to A2 pin of the Nucleo board (not used)
54 | * GND of the VL53L8CX satellite connected to GND of the Nucleo board
55 | */
56 |
57 | /* Includes ------------------------------------------------------------------*/
58 |
59 | #include
60 |
61 |
62 | #ifdef ARDUINO_SAM_DUE
63 | #define DEV_I2C Wire1
64 | #else
65 | #define DEV_I2C Wire
66 | #endif
67 | #define SerialPort Serial
68 |
69 | #define LPN_PIN A3
70 | #define PWREN_PIN 11
71 |
72 | void print_result(VL53L8CX_ResultsData *Result);
73 | void clear_screen(void);
74 | void handle_cmd(uint8_t cmd);
75 | void display_commands_banner(void);
76 |
77 | // Components.
78 | VL53L8CX sensor_vl53l8cx_top(&DEV_I2C, LPN_PIN);
79 |
80 | bool EnableAmbient = false;
81 | bool EnableSignal = false;
82 | uint8_t res = VL53L8CX_RESOLUTION_4X4;
83 | char report[256];
84 | uint8_t status;
85 |
86 | /* Setup ---------------------------------------------------------------------*/
87 | void setup()
88 | {
89 |
90 | // Enable PWREN pin if present
91 | if (PWREN_PIN >= 0) {
92 | pinMode(PWREN_PIN, OUTPUT);
93 | digitalWrite(PWREN_PIN, HIGH);
94 | delay(10);
95 | }
96 |
97 | // Initialize serial for output.
98 | SerialPort.begin(460800);
99 |
100 | // Initialize I2C bus.
101 | DEV_I2C.begin();
102 |
103 | // Configure VL53L8CX component.
104 | sensor_vl53l8cx_top.begin();
105 | status = sensor_vl53l8cx_top.init();
106 |
107 | // Start Measurements
108 | status = sensor_vl53l8cx_top.start_ranging();
109 | }
110 |
111 | void loop()
112 | {
113 | VL53L8CX_ResultsData Results;
114 | uint8_t NewDataReady = 0;
115 |
116 | do {
117 | status = sensor_vl53l8cx_top.check_data_ready(&NewDataReady);
118 | } while (!NewDataReady);
119 |
120 | if ((!status) && (NewDataReady != 0)) {
121 | status = sensor_vl53l8cx_top.get_ranging_data(&Results);
122 | print_result(&Results);
123 | }
124 |
125 | if (Serial.available() > 0) {
126 | handle_cmd(Serial.read());
127 | }
128 | delay(100);
129 | }
130 |
131 | void print_result(VL53L8CX_ResultsData *Result)
132 | {
133 | int8_t i, j, k;
134 | uint8_t l, zones_per_line;
135 | uint8_t number_of_zones = res;
136 |
137 | zones_per_line = (number_of_zones == 16) ? 4 : 8;
138 |
139 | display_commands_banner();
140 |
141 | SerialPort.print("Cell Format :\n\n");
142 |
143 | for (l = 0; l < VL53L8CX_NB_TARGET_PER_ZONE; l++) {
144 | snprintf(report, sizeof(report), " \033[38;5;10m%20s\033[0m : %20s\n", "Distance [mm]", "Status");
145 | SerialPort.print(report);
146 |
147 | if (EnableAmbient || EnableSignal) {
148 | snprintf(report, sizeof(report), " %20s : %20s\n", "Signal [kcps/spad]", "Ambient [kcps/spad]");
149 | SerialPort.print(report);
150 | }
151 | }
152 |
153 | SerialPort.print("\n\n");
154 |
155 | for (j = 0; j < number_of_zones; j += zones_per_line) {
156 | for (i = 0; i < zones_per_line; i++) {
157 | SerialPort.print(" -----------------");
158 | }
159 | SerialPort.print("\n");
160 |
161 | for (i = 0; i < zones_per_line; i++) {
162 | SerialPort.print("| ");
163 | }
164 | SerialPort.print("|\n");
165 |
166 | for (l = 0; l < VL53L8CX_NB_TARGET_PER_ZONE; l++) {
167 | // Print distance and status
168 | for (k = (zones_per_line - 1); k >= 0; k--) {
169 | if (Result->nb_target_detected[j + k] > 0) {
170 | snprintf(report, sizeof(report), "| \033[38;5;10m%5ld\033[0m : %5ld ",
171 | (long)Result->distance_mm[(VL53L8CX_NB_TARGET_PER_ZONE * (j + k)) + l],
172 | (long)Result->target_status[(VL53L8CX_NB_TARGET_PER_ZONE * (j + k)) + l]);
173 | SerialPort.print(report);
174 | } else {
175 | snprintf(report, sizeof(report), "| %5s : %5s ", "X", "X");
176 | SerialPort.print(report);
177 | }
178 | }
179 | SerialPort.print("|\n");
180 |
181 | if (EnableAmbient || EnableSignal) {
182 | // Print Signal and Ambient
183 | for (k = (zones_per_line - 1); k >= 0; k--) {
184 | if (Result->nb_target_detected[j + k] > 0) {
185 | if (EnableSignal) {
186 | snprintf(report, sizeof(report), "| %5ld : ", (long)Result->signal_per_spad[(VL53L8CX_NB_TARGET_PER_ZONE * (j + k)) + l]);
187 | SerialPort.print(report);
188 | } else {
189 | snprintf(report, sizeof(report), "| %5s : ", "X");
190 | SerialPort.print(report);
191 | }
192 | if (EnableAmbient) {
193 | snprintf(report, sizeof(report), "%5ld ", (long)Result->ambient_per_spad[j + k]);
194 | SerialPort.print(report);
195 | } else {
196 | snprintf(report, sizeof(report), "%5s ", "X");
197 | SerialPort.print(report);
198 | }
199 | } else {
200 | snprintf(report, sizeof(report), "| %5s : %5s ", "X", "X");
201 | SerialPort.print(report);
202 | }
203 | }
204 | SerialPort.print("|\n");
205 | }
206 | }
207 | }
208 | for (i = 0; i < zones_per_line; i++) {
209 | SerialPort.print(" -----------------");
210 | }
211 | SerialPort.print("\n");
212 | }
213 |
214 | void toggle_resolution(void)
215 | {
216 | status = sensor_vl53l8cx_top.stop_ranging();
217 |
218 | switch (res) {
219 | case VL53L8CX_RESOLUTION_4X4:
220 | res = VL53L8CX_RESOLUTION_8X8;
221 | break;
222 |
223 | case VL53L8CX_RESOLUTION_8X8:
224 | res = VL53L8CX_RESOLUTION_4X4;
225 | break;
226 |
227 | default:
228 | break;
229 | }
230 | status = sensor_vl53l8cx_top.set_resolution(res);
231 | status = sensor_vl53l8cx_top.start_ranging();
232 | }
233 |
234 | void toggle_signal_and_ambient(void)
235 | {
236 | EnableAmbient = (EnableAmbient) ? false : true;
237 | EnableSignal = (EnableSignal) ? false : true;
238 | }
239 |
240 | void clear_screen(void)
241 | {
242 | snprintf(report, sizeof(report), "%c[2J", 27); /* 27 is ESC command */
243 | SerialPort.print(report);
244 | }
245 |
246 | void display_commands_banner(void)
247 | {
248 | snprintf(report, sizeof(report), "%c[2H", 27); /* 27 is ESC command */
249 | SerialPort.print(report);
250 |
251 | Serial.print("53L8A1 Simple Ranging demo application\n");
252 | Serial.print("--------------------------------------\n\n");
253 |
254 | Serial.print("Use the following keys to control application\n");
255 | Serial.print(" 'r' : change resolution\n");
256 | Serial.print(" 's' : enable signal and ambient\n");
257 | Serial.print(" 'c' : clear screen\n");
258 | Serial.print("\n");
259 | }
260 |
261 | void handle_cmd(uint8_t cmd)
262 | {
263 | switch (cmd) {
264 | case 'r':
265 | toggle_resolution();
266 | clear_screen();
267 | break;
268 |
269 | case 's':
270 | toggle_signal_and_ambient();
271 | clear_screen();
272 | break;
273 |
274 | case 'c':
275 | clear_screen();
276 | break;
277 |
278 | default:
279 | break;
280 | }
281 | }
282 |
--------------------------------------------------------------------------------
/examples/VL53L8CX_HelloWorld_SPI/VL53L8CX_HelloWorld_SPI.ino:
--------------------------------------------------------------------------------
1 | /**
2 | ******************************************************************************
3 | * @file VL53L8CX_HelloWorld_SPI.ino
4 | * @author STMicroelectronics
5 | * @version V2.0.0
6 | * @date 27 June 2024
7 | * @brief Arduino test application for the X-NUCLEO-53L8A1 based on VL53L8CX
8 | * proximity sensor.
9 | * This application makes use of C++ classes obtained from the C
10 | * components' drivers.
11 | ******************************************************************************
12 | * @attention
13 | *
14 | * © COPYRIGHT(c) 2024 STMicroelectronics
15 | *
16 | * Redistribution and use in source and binary forms, with or without modification,
17 | * are permitted provided that the following conditions are met:
18 | * 1. Redistributions of source code must retain the above copyright notice,
19 | * this list of conditions and the following disclaimer.
20 | * 2. Redistributions in binary form must reproduce the above copyright notice,
21 | * this list of conditions and the following disclaimer in the documentation
22 | * and/or other materials provided with the distribution.
23 | * 3. Neither the name of STMicroelectronics nor the names of its contributors
24 | * may be used to endorse or promote products derived from this software
25 | * without specific prior written permission.
26 | *
27 | * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
28 | * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
29 | * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
30 | * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
31 | * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
32 | * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
33 | * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
34 | * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
35 | * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
36 | * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
37 | *
38 | ******************************************************************************
39 | */
40 | /*
41 | * To use these examples you need to connect the VL53L8CX satellite sensor directly to the Nucleo board with wires as explained below:
42 | * pin 1 (SPI_I2C_n) of the VL53L8CX satellite connected to 3V3 of the Nucleo board
43 | * pin 2 (LPn) of the VL53L8CX satellite connected to 3V3 of the Nucleo board
44 | * pin 3 (NCS) of the VL53L8CX satellite connected to pin D10 of the Nucleo board
45 | * pin 4 (MISO) of the VL53L8CX satellite connected to pin D5 of the Nucleo board
46 | * pin 5 (MOSI_SDA) of the VL53L8CX satellite connected to pin D4 (MOSI) of the Nucleo board
47 | * pin 6 (MCLK_SCL) of the VL53L8CX satellite connected to pin D3 (MCLK_SCL) of the Nucleo board
48 | * pin 7 (PWREN) of the VL53L8CX satellite connected to pin D11 of the Nucleo board
49 | * pin 8 (I0VDD) of the VL53L8CX satellite not connected
50 | * pin 9 (3V3) of the VL53L8CX satellite not connected
51 | * pin 10 (1V8) of the VL53L8CX satellite not connected
52 | * pin 11 (5V) of the VL53L8CX satellite connected to 5V of the Nucleo board
53 | * GPIO1 of VL53L8CX satellite connected to A2 pin of the Nucleo board (not used)
54 | * GND of the VL53L8CX satellite connected to GND of the Nucleo board
55 | */
56 |
57 | /* Includes ------------------------------------------------------------------*/
58 |
59 | #include
60 | #include
61 |
62 | #define SerialPort Serial
63 |
64 | #define PWREN_PIN 11
65 |
66 | #define SPI_CLK_PIN 3
67 | #define SPI_MISO_PIN 5
68 | #define SPI_MOSI_PIN 4
69 | #define CS_PIN 10
70 |
71 | SPIClass DEV_SPI(SPI_MOSI_PIN, SPI_MISO_PIN, SPI_CLK_PIN);
72 |
73 | void print_result(VL53L8CX_ResultsData *Result);
74 | void clear_screen(void);
75 | void handle_cmd(uint8_t cmd);
76 | void display_commands_banner(void);
77 |
78 | VL53L8CX sensor_vl53l8cx_top(&DEV_SPI, CS_PIN);
79 |
80 | bool EnableAmbient = false;
81 | bool EnableSignal = false;
82 | uint8_t res = VL53L8CX_RESOLUTION_4X4;
83 | char report[256];
84 | uint8_t status;
85 | /* Setup ---------------------------------------------------------------------*/
86 | void setup()
87 | {
88 | // Enable PWREN pin if present
89 | if (PWREN_PIN >= 0) {
90 | pinMode(PWREN_PIN, OUTPUT);
91 | digitalWrite(PWREN_PIN, HIGH);
92 | delay(10);
93 | }
94 |
95 | // Initialize serial for output.
96 | SerialPort.begin(460800);
97 |
98 | // Initialize SPI bus.
99 | DEV_SPI.begin();
100 |
101 | // Configure VL53L8CX component.
102 | sensor_vl53l8cx_top.begin();
103 | status = sensor_vl53l8cx_top.init();
104 |
105 | // Start Measurements
106 | status = sensor_vl53l8cx_top.start_ranging();
107 | }
108 |
109 | void loop()
110 | {
111 | VL53L8CX_ResultsData Results;
112 | uint8_t NewDataReady = 0;
113 | do {
114 | status = sensor_vl53l8cx_top.check_data_ready(&NewDataReady);
115 | } while (!NewDataReady);
116 |
117 | if ((!status) && (NewDataReady != 0)) {
118 | status = sensor_vl53l8cx_top.get_ranging_data(&Results);
119 | print_result(&Results);
120 | }
121 |
122 | if (Serial.available() > 0) {
123 | handle_cmd(Serial.read());
124 | }
125 | delay(50);
126 | }
127 |
128 | void print_result(VL53L8CX_ResultsData *Result)
129 | {
130 | int8_t i, j, k;
131 | uint8_t l, zones_per_line;
132 | uint8_t number_of_zones = res;
133 |
134 | zones_per_line = (number_of_zones == 16) ? 4 : 8;
135 |
136 | display_commands_banner();
137 |
138 | SerialPort.print("Cell Format :\n\n");
139 |
140 | for (l = 0; l < VL53L8CX_NB_TARGET_PER_ZONE; l++) {
141 | snprintf(report, sizeof(report), " \033[38;5;10m%20s\033[0m : %20s\n", "Distance [mm]", "Status");
142 | SerialPort.print(report);
143 |
144 | if (EnableAmbient || EnableSignal) {
145 | snprintf(report, sizeof(report), " %20s : %20s\n", "Signal [kcps/spad]", "Ambient [kcps/spad]");
146 | SerialPort.print(report);
147 | }
148 | }
149 |
150 | SerialPort.print("\n\n");
151 |
152 | for (j = 0; j < number_of_zones; j += zones_per_line) {
153 | for (i = 0; i < zones_per_line; i++) {
154 | SerialPort.print(" -----------------");
155 | }
156 | SerialPort.print("\n");
157 |
158 | for (i = 0; i < zones_per_line; i++) {
159 | SerialPort.print("| ");
160 | }
161 | SerialPort.print("|\n");
162 |
163 | for (l = 0; l < VL53L8CX_NB_TARGET_PER_ZONE; l++) {
164 | // Print distance and status
165 | for (k = (zones_per_line - 1); k >= 0; k--) {
166 | if (Result->nb_target_detected[j + k] > 0) {
167 | snprintf(report, sizeof(report), "| \033[38;5;10m%5ld\033[0m : %5ld ",
168 | (long)Result->distance_mm[(VL53L8CX_NB_TARGET_PER_ZONE * (j + k)) + l],
169 | (long)Result->target_status[(VL53L8CX_NB_TARGET_PER_ZONE * (j + k)) + l]);
170 | SerialPort.print(report);
171 | } else {
172 | snprintf(report, sizeof(report), "| %5s : %5s ", "X", "X");
173 | SerialPort.print(report);
174 | }
175 | }
176 | SerialPort.print("|\n");
177 |
178 | if (EnableAmbient || EnableSignal) {
179 | // Print Signal and Ambient
180 | for (k = (zones_per_line - 1); k >= 0; k--) {
181 | if (Result->nb_target_detected[j + k] > 0) {
182 | if (EnableSignal) {
183 | snprintf(report, sizeof(report), "| %5ld : ", (long)Result->signal_per_spad[(VL53L8CX_NB_TARGET_PER_ZONE * (j + k)) + l]);
184 | SerialPort.print(report);
185 | } else {
186 | snprintf(report, sizeof(report), "| %5s : ", "X");
187 | SerialPort.print(report);
188 | }
189 | if (EnableAmbient) {
190 | snprintf(report, sizeof(report), "%5ld ", (long)Result->ambient_per_spad[j + k]);
191 | SerialPort.print(report);
192 | } else {
193 | snprintf(report, sizeof(report), "%5s ", "X");
194 | SerialPort.print(report);
195 | }
196 | } else {
197 | snprintf(report, sizeof(report), "| %5s : %5s ", "X", "X");
198 | SerialPort.print(report);
199 | }
200 | }
201 | SerialPort.print("|\n");
202 | }
203 | }
204 | }
205 | for (i = 0; i < zones_per_line; i++) {
206 | SerialPort.print(" -----------------");
207 | }
208 | SerialPort.print("\n");
209 | }
210 |
211 | void toggle_resolution(void)
212 | {
213 | status = sensor_vl53l8cx_top.stop_ranging();
214 |
215 | switch (res) {
216 | case VL53L8CX_RESOLUTION_4X4:
217 | res = VL53L8CX_RESOLUTION_8X8;
218 | break;
219 |
220 | case VL53L8CX_RESOLUTION_8X8:
221 | res = VL53L8CX_RESOLUTION_4X4;
222 | break;
223 |
224 | default:
225 | break;
226 | }
227 | status = sensor_vl53l8cx_top.set_resolution(res);
228 | status = sensor_vl53l8cx_top.start_ranging();
229 | }
230 |
231 | void toggle_signal_and_ambient(void)
232 | {
233 | EnableAmbient = (EnableAmbient) ? false : true;
234 | EnableSignal = (EnableSignal) ? false : true;
235 | }
236 |
237 | void clear_screen(void)
238 | {
239 | snprintf(report, sizeof(report), "%c[2J", 27); /* 27 is ESC command */
240 | SerialPort.print(report);
241 | }
242 |
243 | void display_commands_banner(void)
244 | {
245 | snprintf(report, sizeof(report), "%c[2H", 27); /* 27 is ESC command */
246 | SerialPort.print(report);
247 |
248 | Serial.print("53L8A1 Simple Ranging demo application\n");
249 | Serial.print("--------------------------------------\n\n");
250 |
251 | Serial.print("Use the following keys to control application\n");
252 | Serial.print(" 'r' : change resolution\n");
253 | Serial.print(" 's' : enable signal and ambient\n");
254 | Serial.print(" 'c' : clear screen\n");
255 | Serial.print("\n");
256 | }
257 |
258 | void handle_cmd(uint8_t cmd)
259 | {
260 | switch (cmd) {
261 | case 'r':
262 | toggle_resolution();
263 | clear_screen();
264 | break;
265 |
266 | case 's':
267 | toggle_signal_and_ambient();
268 | clear_screen();
269 | break;
270 |
271 | case 'c':
272 | clear_screen();
273 | break;
274 |
275 | default:
276 | break;
277 | }
278 | }
279 |
--------------------------------------------------------------------------------
/examples/VL53L8CX_ThresholdDetection/VL53L8CX_ThresholdDetection.ino:
--------------------------------------------------------------------------------
1 | /**
2 | ******************************************************************************
3 | * @file VL53L8CX_ThresholdDetection.ino
4 | * @author STMicroelectronics
5 | * @version V2.0.0
6 | * @date 27 June 2024
7 | * @brief Arduino test application for the STMicrolectronics VL53L8CX
8 | * proximity sensor satellite based on FlightSense.
9 | * This application makes use of C++ classes obtained from the C
10 | * components' drivers.
11 | ******************************************************************************
12 | * @attention
13 | *
14 | * © COPYRIGHT(c) 2024 STMicroelectronics
15 | *
16 | * Redistribution and use in source and binary forms, with or without modification,
17 | * are permitted provided that the following conditions are met:
18 | * 1. Redistributions of source code must retain the above copyright notice,
19 | * this list of conditions and the following disclaimer.
20 | * 2. Redistributions in binary form must reproduce the above copyright notice,
21 | * this list of conditions and the following disclaimer in the documentation
22 | * and/or other materials provided with the distribution.
23 | * 3. Neither the name of STMicroelectronics nor the names of its contributors
24 | * may be used to endorse or promote products derived from this software
25 | * without specific prior written permission.
26 | *
27 | * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
28 | * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
29 | * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
30 | * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
31 | * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
32 | * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
33 | * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
34 | * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
35 | * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
36 | * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
37 | *
38 | ******************************************************************************
39 | */
40 | /*
41 | * To use these examples you need to connect the VL53L8CX satellite sensor directly to the Nucleo board with wires as explained below:
42 | * pin 1 (SPI_I2C_n) of the VL53L8CX satellite connected to pin GND of the Nucleo board
43 | * pin 2 (LPn) of the VL53L8CX satellite connected to pin A3 of the Nucleo board
44 | * pin 3 (NCS) not connected
45 | * pin 4 (MISO) not connected
46 | * pin 5 (MOSI_SDA) of the VL53L8CX satellite connected to pin D14 (SDA) of the Nucleo board
47 | * pin 6 (MCLK_SCL) of the VL53L8CX satellite connected to pin D15 (SCL) of the Nucleo board
48 | * pin 7 (PWREN) of the VL53L8CX satellite connected to pin D11 of the Nucleo board
49 | * pin 8 (I0VDD) of the VL53L8CX satellite not connected
50 | * pin 9 (3V3) of the VL53L8CX satellite not connected
51 | * pin 10 (1V8) of the VL53L8CX satellite not connected
52 | * pin 11 (5V) of the VL53L8CX satellite connected to 5V of the Nucleo board
53 | * GPIO1 of VL53L8CX satellite connected to A2 pin of the Nucleo board (not used)
54 | * GND of the VL53L8CX satellite connected to GND of the Nucleo board
55 | */
56 |
57 | /* Includes ------------------------------------------------------------------*/
58 |
59 | #include
60 |
61 | #ifdef ARDUINO_SAM_DUE
62 | #define DEV_I2C Wire1
63 | #else
64 | #define DEV_I2C Wire
65 | #endif
66 | #define SerialPort Serial
67 |
68 | #define LPN_PIN A3
69 | #define PWREN_PIN 11
70 | #define INT_PIN A2
71 |
72 | void measure(void);
73 | void print_result(VL53L8CX_ResultsData *Result);
74 |
75 | // Component.
76 | VL53L8CX sensor_VL53L8CX_top(&DEV_I2C, LPN_PIN);
77 |
78 | bool EnableAmbient = false;
79 | bool EnableSignal = false;
80 | uint8_t res = VL53L8CX_RESOLUTION_4X4;
81 | char report[256];
82 | volatile int interruptCount = 0;
83 | uint8_t i;
84 | uint8_t status;
85 |
86 | /* Setup ---------------------------------------------------------------------*/
87 |
88 | void setup()
89 | {
90 |
91 | VL53L8CX_DetectionThresholds thresholds[VL53L8CX_NB_THRESHOLDS];
92 |
93 | // Enable PWREN pin if present
94 | if (PWREN_PIN >= 0) {
95 | pinMode(PWREN_PIN, OUTPUT);
96 | digitalWrite(PWREN_PIN, HIGH);
97 | delay(10);
98 | }
99 |
100 | // Initialize serial for output.
101 | SerialPort.begin(460800);
102 |
103 | // Initialize I2C bus.
104 | DEV_I2C.begin();
105 |
106 | // Set interrupt pin
107 | pinMode(INT_PIN, INPUT_PULLUP);
108 | attachInterrupt(INT_PIN, measure, FALLING);
109 |
110 | // Configure VL53L8CX component.
111 | sensor_VL53L8CX_top.begin();
112 | status = sensor_VL53L8CX_top.init();
113 |
114 | // Disable thresholds detection.
115 | status = sensor_VL53L8CX_top.set_detection_thresholds_enable(0U);
116 |
117 | // Set all values to 0.
118 | memset(&thresholds, 0, sizeof(thresholds));
119 |
120 | // Configure thresholds on each active zone
121 | for (i = 0; i < res; i++) {
122 | thresholds[i].zone_num = i;
123 | thresholds[i].measurement = VL53L8CX_DISTANCE_MM;
124 | thresholds[i].type = VL53L8CX_IN_WINDOW;
125 | thresholds[i].mathematic_operation = VL53L8CX_OPERATION_NONE;
126 | thresholds[i].param_low_thresh = 200;
127 | thresholds[i].param_high_thresh = 600;
128 | }
129 |
130 | // Last threshold must be clearly indicated.
131 | thresholds[i].zone_num |= VL53L8CX_LAST_THRESHOLD;
132 |
133 | // Send array of thresholds to the sensor.
134 | status = sensor_VL53L8CX_top.set_detection_thresholds(thresholds);
135 |
136 | // Enable thresholds detection.
137 | status = sensor_VL53L8CX_top.set_detection_thresholds_enable(1U);
138 |
139 | // Start Measurements.
140 | status = sensor_VL53L8CX_top.start_ranging();
141 | }
142 |
143 | void loop()
144 | {
145 | VL53L8CX_ResultsData Results;
146 | uint8_t NewDataReady = 0;
147 | do {
148 | status = sensor_VL53L8CX_top.check_data_ready(&NewDataReady);
149 | } while (!NewDataReady);
150 |
151 | if ((!status) && (NewDataReady != 0) && interruptCount) {
152 | interruptCount = 0;
153 | status = sensor_VL53L8CX_top.get_ranging_data(&Results);
154 | print_result(&Results);
155 | }
156 |
157 | }
158 |
159 | void print_result(VL53L8CX_ResultsData *Result)
160 | {
161 | int8_t i, j, k;
162 | uint8_t l, zones_per_line;
163 | uint8_t number_of_zones = res;
164 |
165 | zones_per_line = (number_of_zones == 16) ? 4 : 8;
166 |
167 | snprintf(report, sizeof(report), "%c[2H", 27); /* 27 is ESC command */
168 | SerialPort.print(report);
169 | SerialPort.print("53L8A1 Threshold Detection demo application\n");
170 | SerialPort.print("-------------------------------------------\n\n");
171 | SerialPort.print("Cell Format :\n\n");
172 |
173 | for (l = 0; l < VL53L8CX_NB_TARGET_PER_ZONE; l++) {
174 | snprintf(report, sizeof(report), " \033[38;5;10m%20s\033[0m : %20s\n", "Distance [mm]", "Status");
175 | SerialPort.print(report);
176 |
177 | if (EnableAmbient || EnableSignal) {
178 | snprintf(report, sizeof(report), " %20s : %20s\n", "Signal [kcps/spad]", "Ambient [kcps/spad]");
179 | SerialPort.print(report);
180 | }
181 | }
182 |
183 | SerialPort.print("\n\n");
184 |
185 | for (j = 0; j < number_of_zones; j += zones_per_line) {
186 | for (i = 0; i < zones_per_line; i++) {
187 | SerialPort.print(" -----------------");
188 | }
189 | SerialPort.print("\n");
190 |
191 | for (i = 0; i < zones_per_line; i++) {
192 | SerialPort.print("| ");
193 | }
194 | SerialPort.print("|\n");
195 |
196 | for (l = 0; l < VL53L8CX_NB_TARGET_PER_ZONE; l++) {
197 | // Print distance and status.
198 | for (k = (zones_per_line - 1); k >= 0; k--) {
199 | if (Result->nb_target_detected[j + k] > 0) {
200 | snprintf(report, sizeof(report), "| \033[38;5;10m%5ld\033[0m : %5ld ",
201 | (long)Result->distance_mm[(VL53L8CX_NB_TARGET_PER_ZONE * (j + k)) + l],
202 | (long)Result->target_status[(VL53L8CX_NB_TARGET_PER_ZONE * (j + k)) + l]);
203 | SerialPort.print(report);
204 | } else {
205 | snprintf(report, sizeof(report), "| %5s : %5s ", "X", "X");
206 | SerialPort.print(report);
207 | }
208 | }
209 | SerialPort.print("|\n");
210 |
211 | if (EnableAmbient || EnableSignal) {
212 | // Print Signal and Ambient.
213 | for (k = (zones_per_line - 1); k >= 0; k--) {
214 | if (Result->nb_target_detected[j + k] > 0) {
215 | if (EnableSignal) {
216 | snprintf(report, sizeof(report), "| %5ld : ", (long)Result->signal_per_spad[(VL53L8CX_NB_TARGET_PER_ZONE * (j + k)) + l]);
217 | SerialPort.print(report);
218 | } else {
219 | snprintf(report, sizeof(report), "| %5s : ", "X");
220 | SerialPort.print(report);
221 | }
222 | if (EnableAmbient) {
223 | snprintf(report, sizeof(report), "%5ld ", (long)Result->ambient_per_spad[j + k]);
224 | SerialPort.print(report);
225 | } else {
226 | snprintf(report, sizeof(report), "%5s ", "X");
227 | SerialPort.print(report);
228 | }
229 | } else {
230 | snprintf(report, sizeof(report), "| %5s : %5s ", "X", "X");
231 | SerialPort.print(report);
232 | }
233 | }
234 | SerialPort.print("|\n");
235 | }
236 | }
237 | }
238 | for (i = 0; i < zones_per_line; i++) {
239 | SerialPort.print(" -----------------");
240 | }
241 | SerialPort.print("\n");
242 | }
243 |
244 | void measure(void)
245 | {
246 | interruptCount = 1;
247 | }
248 |
--------------------------------------------------------------------------------
/keywords.txt:
--------------------------------------------------------------------------------
1 | #######################################
2 | # Syntax Coloring Map For VL53L8CX
3 | #######################################
4 |
5 | #######################################
6 | # Datatypes (KEYWORD1)
7 | #######################################
8 |
9 | VL53L8CX KEYWORD1
10 |
11 | #######################################
12 | # Methods and Functions (KEYWORD2)
13 | #######################################
14 |
15 | begin KEYWORD2
16 | end KEYWORD2
17 | on KEYWORD2
18 | off KEYWORD2
19 | is_alive KEYWORD2
20 | init KEYWORD2
21 | set_i2c_address KEYWORD2
22 | get_power_mode KEYWORD2
23 | set_power_mode KEYWORD2
24 | start_ranging KEYWORD2
25 | stop_ranging KEYWORD2
26 | check_data_ready KEYWORD2
27 | get_ranging_data KEYWORD2
28 | get_resolution KEYWORD2
29 | set_resolution KEYWORD2
30 | get_ranging_frequency_hz KEYWORD2
31 | set_ranging_frequency_hz KEYWORD2
32 | get_integration_time_ms KEYWORD2
33 | set_integration_time_ms KEYWORD2
34 | get_sharpener_percent KEYWORD2
35 | set_sharpener_percent KEYWORD2
36 | get_target_order KEYWORD2
37 | set_target_order KEYWORD2
38 | get_ranging_mode KEYWORD2
39 | set_ranging_mode KEYWORD2
40 | get_external_sync_pin_enable KEYWORD2
41 | set_external_sync_pin_enable KEYWORD2
42 | get_VHV_repeat_count KEYWORD2
43 | set_VHV_repeat_count KEYWORD2
44 | dci_read_data KEYWORD2
45 | dci_write_data KEYWORD2
46 | dci_replace_data KEYWORD2
47 | get_detection_thresholds_enable KEYWORD2
48 | set_detection_thresholds_enable KEYWORD2
49 | get_detection_thresholds KEYWORD2
50 | set_detection_thresholds KEYWORD2
51 | get_detection_thresholds_auto_stop KEYWORD2
52 | set_detection_thresholds_auto_stop
53 | motion_indicator_init KEYWORD2 KEYWORD2
54 | motion_indicator_set_distance_motion KEYWORD2
55 | motion_indicator_set_resolution KEYWORD2
56 | calibrate_xtalk KEYWORD2
57 | get_caldata_xtalk KEYWORD2
58 | set_caldata_xtalk KEYWORD2
59 | get_xtalk_margin KEYWORD2
60 | set_xtalk_margin KEYWORD2
61 | SwapBuffer KEYWORD2
62 | get_stream_count KEYWORD2
63 |
64 | #######################################
65 | # Constants (LITERAL1)
66 | #######################################
67 |
68 | DEFAULT_I2C_BUFFER_LEN LITERAL1
69 | VL53L8CX_NB_TARGET_PER_ZONE LITERAL1
70 | VL53L8CX_API_REVISION LITERAL1
71 | VL53L8CX_DEFAULT_I2C_ADDRESS LITERAL1
72 | VL53L8CX_RESOLUTION_4X4 LITERAL1
73 | VL53L8CX_RESOLUTION_8X8 LITERAL1
74 | VL53L8CX_TARGET_ORDER_CLOSEST LITERAL1
75 | VL53L8CX_TARGET_ORDER_STRONGEST LITERAL1
76 | VL53L8CX_RANGING_MODE_CONTINUOUS LITERAL1
77 | VL53L8CX_RANGING_MODE_AUTONOMOUS LITERAL1
78 | VL53L8CX_POWER_MODE_SLEEP LITERAL1
79 | VL53L8CX_POWER_MODE_WAKEUP LITERAL1
80 | VL53L8CX_STATUS_OK LITERAL1
81 | VL53L8CX_MCU_ERROR LITERAL1
82 | VL53L8CX_STATUS_INVALID_PARAM LITERAL1
83 | VL53L8CX_STATUS_ERROR LITERAL1
84 | VL53L8CX_START_BH LITERAL1
85 | VL53L8CX_METADATA_BH LITERAL1
86 | VL53L8CX_COMMONDATA_BH LITERAL1
87 | VL53L8CX_AMBIENT_RATE_BH LITERAL1
88 | VL53L8CX_SPAD_COUNT_BH LITERAL1
89 | VL53L8CX_NB_TARGET_DETECTED_BH LITERAL1
90 | VL53L8CX_SIGNAL_RATE_BH LITERAL1
91 | VL53L8CX_RANGE_SIGMA_MM_BH LITERAL1
92 | VL53L8CX_DISTANCE_BH LITERAL1
93 | VL53L8CX_REFLECTANCE_BH LITERAL1
94 | VL53L8CX_TARGET_STATUS_BH LITERAL1
95 | VL53L8CX_MOTION_DETECT_BH LITERAL1
96 | VL53L8CX_METADATA_IDX LITERAL1
97 | VL53L8CX_SPAD_COUNT_IDX LITERAL1
98 | VL53L8CX_AMBIENT_RATE_IDX LITERAL1
99 | VL53L8CX_NB_TARGET_DETECTED_IDX LITERAL1
100 | VL53L8CX_SIGNAL_RATE_IDX LITERAL1
101 | VL53L8CX_RANGE_SIGMA_MM_IDX LITERAL1
102 | VL53L8CX_DISTANCE_IDX LITERAL1
103 | VL53L8CX_REFLECTANCE_EST_PC_IDX LITERAL1
104 | VL53L8CX_TARGET_STATUS_IDX LITERAL1
105 | VL53L8CX_MOTION_DETEC_IDX LITERAL1
106 | VL53L8CX_NVM_DATA_SIZE LITERAL1
107 | VL53L8CX_CONFIGURATION_SIZE LITERAL1
108 | VL53L8CX_OFFSET_BUFFER_SIZE LITERAL1
109 | VL53L8CX_XTALK_BUFFER_SIZE LITERAL1
110 | VL53L8CX_DCI_ZONE_CONFIG LITERAL1
111 | VL53L8CX_DCI_FREQ_HZ LITERAL1
112 | VL53L8CX_DCI_INT_TIME LITERAL1
113 | VL53L8CX_DCI_FW_NB_TARGET LITERAL1
114 | VL53L8CX_DCI_RANGING_MODE LITERAL1
115 | VL53L8CX_DCI_DSS_CONFIG LITERAL1
116 | VL53L8CX_DCI_TARGET_ORDER LITERAL1
117 | VL53L8CX_DCI_SHARPENER LITERAL1
118 | VL53L8CX_DCI_MOTION_DETECTOR_CFG LITERAL1
119 | VL53L8CX_DCI_SINGLE_RANGE LITERAL1
120 | VL53L8CX_DCI_OUTPUT_CONFIG LITERAL1
121 | VL53L8CX_DCI_OUTPUT_ENABLES LITERAL1
122 | VL53L8CX_DCI_OUTPUT_LIST LITERAL1
123 | VL53L8CX_DCI_PIPE_CONTROL LITERAL1
124 | VL53L8CX_UI_CMD_STATUS LITERAL1
125 | VL53L8CX_UI_CMD_START LITERAL1
126 | VL53L8CX_UI_CMD_END LITERAL1
127 | L5CX_AMB_SIZE LITERAL1
128 | L5CX_SPAD_SIZE LITERAL1
129 | L5CX_NTAR_SIZE LITERAL1
130 | L5CX_SPS_SIZE LITERAL1
131 | L5CX_SIGR_SIZE LITERAL1
132 | L5CX_DIST_SIZE LITERAL1
133 | L5CX_RFLEST_SIZE LITERAL1
134 | L5CX_STA_SIZE LITERAL1
135 | L5CX_MOT_SIZE LITERAL1
136 | VL53L8CX_MAX_RESULTS_SIZE LITERAL1
137 | VL53L8CX_TEMPORARY_BUFFER_SIZE LITERAL1
138 | VL53L8CX_FW_NBTAR_RANGING LITERAL1
139 | VL53L8CX_NB_THRESHOLDS LITERAL1
140 | VL53L8CX_DCI_DET_THRESH_CONFIG LITERAL1
141 | VL53L8CX_DCI_DET_THRESH_GLOBAL_CONFIG LITERAL1
142 | VL53L8CX_DCI_DET_THRESH_START LITERAL1
143 | VL53L8CX_DCI_DET_THRESH_VALID_STATUS LITERAL1
144 | VL53L8CX_LAST_THRESHOLD LITERAL1
145 | VL53L8CX_DISTANCE_MM LITERAL1
146 | VL53L8CX_SIGNAL_PER_SPAD_KCPS LITERAL1
147 | VL53L8CX_RANGE_SIGMA_MM LITERAL1
148 | VL53L8CX_AMBIENT_PER_SPAD_KCPS LITERAL1
149 | VL53L8CX_NB_TARGET_DETECTED LITERAL1
150 | VL53L8CX_TARGET_STATUS LITERAL1
151 | VL53L8CX_NB_SPADS_ENABLED LITERAL1
152 | VL53L8CX_MOTION_INDICATOR LITERAL1
153 | VL53L8CX_IN_WINDOW LITERAL1
154 | VL53L8CX_OUT_OF_WINDOW LITERAL1
155 | VL53L8CX_LESS_THAN_EQUAL_MIN_CHECKER LITERAL1
156 | VL53L8CX_GREATER_THAN_MAX_CHECKER LITERAL1
157 | VL53L8CX_EQUAL_MIN_CHECKER LITERAL1
158 | VL53L8CX_NOT_EQUAL_MIN_CHECKER LITERAL1
159 | VL53L8CX_OPERATION_NONE LITERAL1
160 | VL53L8CX_OPERATION_OR LITERAL1
161 | VL53L8CX_OPERATION_AND LITERAL1
162 | VL53L8CX_FW_NBTAR_XTALK LITERAL1
163 | VL53L8CX_DCI_CAL_CFG LITERAL1
164 | VL53L8CX_DCI_XTALK_CFG LITERAL1
165 |
--------------------------------------------------------------------------------
/library.properties:
--------------------------------------------------------------------------------
1 | name=STM32duino VL53L8CX
2 | version=2.0.3
3 | author=STMicroelectronics
4 | maintainer=stm32duino
5 | sentence=Allows controlling the VL53L8CX (Time-of-Flight 8x8 multizone ranging sensor with wide field view)
6 | paragraph= This library provides simple measure distance in mm
7 | category=Device Control
8 | url= https://github.com/stm32duino/VL53L8CX
9 | architectures=*
10 |
--------------------------------------------------------------------------------
/src/vl53l8cx.cpp:
--------------------------------------------------------------------------------
1 | /**
2 | ******************************************************************************
3 | * @file vl53l8cx.cpp
4 | * @author STMicroelectronics
5 | * @version V2.0.0
6 | * @date 27 June 2024
7 | * @brief Implementation of of a VL53L8CX Time of Flight(TOF) sensor.
8 | ******************************************************************************
9 | * @attention
10 | *
11 | * © COPYRIGHT(c) 2024 STMicroelectronics
12 | *
13 | * Redistribution and use in source and binary forms, with or without modification,
14 | * are permitted provided that the following conditions are met:
15 | * 1. Redistributions of source code must retain the above copyright notice,
16 | * this list of conditions and the following disclaimer.
17 | * 2. Redistributions in binary form must reproduce the above copyright notice,
18 | * this list of conditions and the following disclaimer in the documentation
19 | * and/or other materials provided with the distribution.
20 | * 3. Neither the name of STMicroelectronics nor the names of its contributors
21 | * may be used to endorse or promote products derived from this software
22 | * without specific prior written permission.
23 | *
24 | * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
25 | * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
26 | * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
27 | * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
28 | * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
29 | * DAMAGES(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
30 | * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
31 | * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
32 | * OR TORT(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
33 | * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
34 | *
35 | ******************************************************************************
36 | */
37 |
38 |
39 | /* Includes ------------------------------------------------------------------*/
40 | #include "vl53l8cx.h"
41 |
42 |
43 | /** Constructor
44 | * @param i2c device I2C to be used for communication
45 | * @param _lpn_pin pin to be used as component LPn
46 | * @param _i2c_rst_pin pin to be used as component I2C_RST
47 | */
48 | VL53L8CX::VL53L8CX(TwoWire *i2c, int _lpn_pin, int _i2c_rst_pin): dev_i2c(i2c), lpn_pin(_lpn_pin), i2c_rst_pin(_i2c_rst_pin)
49 | {
50 | memset((void *)&_dev, 0x0, sizeof(VL53L8CX_Configuration));
51 | dev_spi = NULL;
52 | _dev.platform.address = VL53L8CX_DEFAULT_I2C_ADDRESS;
53 | _dev.platform.Write = VL53L8CX_io_write;
54 | _dev.platform.Read = VL53L8CX_io_read;
55 | _dev.platform.Wait = VL53L8CX_io_wait;
56 | _dev.platform.handle = (void *)this;
57 | p_dev = &_dev;
58 | }
59 | /** Constructor
60 | * @param spi object of an helper class which handles the SPI peripheral
61 | * @param _cs_pin the chip select pin
62 | * @param _lpn_pin pin to be used as component LPn
63 | * @param _i2c_rst_pin pin to be used as component I2C_RST
64 | * @param _spi_speed the SPI speed in Hz
65 | */
66 | VL53L8CX::VL53L8CX(SPIClass *spi, int _cs_pin, int _lpn_pin, int _i2c_rst_pin, uint32_t _spi_speed) : dev_spi(spi), cs_pin(_cs_pin), lpn_pin(_lpn_pin), i2c_rst_pin(_i2c_rst_pin), spi_speed(_spi_speed)
67 | {
68 | memset((void *)&_dev, 0x0, sizeof(VL53L8CX_Configuration));
69 | dev_i2c = NULL;
70 | _dev.platform.address = VL53L8CX_DEFAULT_I2C_ADDRESS;
71 | _dev.platform.Write = VL53L8CX_io_write;
72 | _dev.platform.Read = VL53L8CX_io_read;
73 | _dev.platform.Wait = VL53L8CX_io_wait;
74 | _dev.platform.handle = (void *)this;
75 | p_dev = &_dev;
76 | }
77 |
78 | /** Destructor
79 | */
80 | VL53L8CX::~VL53L8CX() {}
81 |
82 | /**
83 | * @brief Initialize the pins of the sensor
84 | * @return Status 0 if check is OK.
85 | */
86 | int VL53L8CX::begin()
87 | {
88 | if (lpn_pin >= 0) {
89 | pinMode(lpn_pin, OUTPUT);
90 | digitalWrite(lpn_pin, LOW);
91 | delay(10);
92 | digitalWrite(lpn_pin, HIGH);
93 | }
94 | if (i2c_rst_pin >= 0) {
95 | pinMode(i2c_rst_pin, OUTPUT);
96 | if (dev_i2c) {
97 | digitalWrite(i2c_rst_pin, LOW);
98 | }
99 | if (dev_spi) {
100 | digitalWrite(i2c_rst_pin, HIGH);
101 | }
102 | }
103 | if (dev_spi) {
104 | // Configure CS pin
105 | pinMode(cs_pin, OUTPUT);
106 | digitalWrite(cs_pin, HIGH);
107 | }
108 | return 0;
109 | }
110 |
111 | /**
112 | * @brief Deinitialize the pins of the sensor
113 | * @return Status 0 if check is OK.
114 | */
115 | int VL53L8CX::end()
116 | {
117 | if (lpn_pin >= 0) {
118 | pinMode(lpn_pin, INPUT);
119 | }
120 | if (i2c_rst_pin >= 0) {
121 | pinMode(i2c_rst_pin, INPUT);
122 | }
123 | /* Reset CS configuration */
124 | if (dev_spi) {
125 | // Configure CS pin
126 | pinMode(cs_pin, INPUT);
127 | }
128 | return 0;
129 | }
130 |
131 | /**
132 | * @brief PowerOn the sensor
133 | * @return void
134 | */
135 | void VL53L8CX::on(void)
136 | {
137 | if (lpn_pin >= 0) {
138 | digitalWrite(lpn_pin, HIGH);
139 | }
140 | delay(10);
141 | }
142 |
143 | /**
144 | * @brief PowerOff the sensor
145 | * @return void
146 | */
147 | void VL53L8CX::off(void)
148 | {
149 | if (lpn_pin >= 0) {
150 | digitalWrite(lpn_pin, LOW);
151 | }
152 | delay(10);
153 | }
154 |
155 | /**
156 | * @brief Reset I2C peripheral of the sensor
157 | * @return void
158 | */
159 | void VL53L8CX::i2c_reset(void)
160 | {
161 | if (dev_i2c && i2c_rst_pin >= 0) {
162 | digitalWrite(i2c_rst_pin, LOW);
163 | delay(10);
164 | digitalWrite(i2c_rst_pin, HIGH);
165 | delay(10);
166 | digitalWrite(i2c_rst_pin, LOW);
167 | delay(10);
168 | }
169 | }
170 |
171 | /**
172 | * @brief Check if the VL53L8CX sensor is alive(responding to I2C communication).
173 | * @param p_is_alive Pointer to the variable that will be set to indicate if the sensor is alive.
174 | * @return Status 0 if check is OK.
175 | */
176 | uint8_t VL53L8CX::is_alive(uint8_t *p_is_alive)
177 | {
178 | return vl53l8cx_is_alive(p_dev, p_is_alive);
179 | }
180 |
181 | /**
182 | * @brief Initialize the VL53L8CX sensor.
183 | * @return Status 0 if initialization is OK.
184 | */
185 | uint8_t VL53L8CX::init(void)
186 | {
187 | return vl53l8cx_init(p_dev);
188 | }
189 |
190 | /**
191 | * @brief Set the I2C address of the VL53L8CX sensor.
192 | * @param i2c_address The new I2C address to be set for the sensor.
193 | * @return Status 0 if the address is set correctly.
194 | */
195 | uint8_t VL53L8CX::set_i2c_address(uint16_t i2c_address)
196 | {
197 | return vl53l8cx_set_i2c_address(p_dev, i2c_address);
198 | }
199 |
200 | /**
201 | * @brief Get the current power mode of the VL53L8CX sensor.
202 | * @param p_power_mode Pointer to the variable that will be set to the current power mode.
203 | * @return Status 0 if the power mode is retrieved successfully.
204 | */
205 | uint8_t VL53L8CX::get_power_mode(uint8_t *p_power_mode)
206 | {
207 | return vl53l8cx_get_power_mode(p_dev, p_power_mode);
208 | }
209 |
210 | /**
211 | * @brief Set the power mode of the VL53L8CX sensor.
212 | * @param power_mode The power mode to be set(e.g., sleep or wakeup).
213 | * @return Status 0 if the power mode is set successfully, or 127 if the requested power mode is not valid.
214 | */
215 | uint8_t VL53L8CX::set_power_mode(uint8_t power_mode)
216 | {
217 | return vl53l8cx_set_power_mode(p_dev, power_mode);
218 | }
219 |
220 | /**
221 | * @brief Start a ranging session with the VL53L8CX sensor.
222 | * @return Status 0 if the ranging session starts successfully.
223 | */
224 | uint8_t VL53L8CX::start_ranging(void)
225 | {
226 | return vl53l8cx_start_ranging(p_dev);
227 | }
228 |
229 | /**
230 | * @brief Stop the current ranging session with the VL53L8CX sensor.
231 | * @return Status 0 if the ranging session stops successfully.
232 | */
233 | uint8_t VL53L8CX::stop_ranging(void)
234 | {
235 | return vl53l8cx_stop_ranging(p_dev);
236 | }
237 |
238 | /**
239 | * @brief Check if new ranging data is ready.
240 | * @param p_isReady Pointer to the variable that will be updated to indicate if new data is ready.
241 | * @return Status 0 if the data ready check is successful.
242 | */
243 | uint8_t VL53L8CX::check_data_ready(uint8_t *p_isReady)
244 | {
245 | return vl53l8cx_check_data_ready(p_dev, p_isReady);
246 | }
247 |
248 | /**
249 | * @brief Get the ranging data from the VL53L8CX sensor.
250 | * @param p_results Pointer to the results data structure where the ranging data will be stored.
251 | * @return Status 0 if the data is retrieved successfully.
252 | */
253 | uint8_t VL53L8CX::get_ranging_data(VL53L8CX_ResultsData *p_results)
254 | {
255 | return vl53l8cx_get_ranging_data(p_dev, p_results);
256 | }
257 |
258 | /**
259 | * @brief Get the current resolution of the VL53L8CX sensor.
260 | * @param p_resolution Pointer to the variable that will be set to the current resolution.
261 | * @return Status 0 if the resolution is retrieved successfully.
262 | */
263 | uint8_t VL53L8CX::get_resolution(uint8_t *p_resolution)
264 | {
265 | return vl53l8cx_get_resolution(p_dev, p_resolution);
266 | }
267 |
268 | /**
269 | * @brief Set a new resolution for the VL53L8CX sensor.
270 | * @param resolution The new resolution to be set.
271 | * @return Status 0 if the resolution is set successfully.
272 | */
273 | uint8_t VL53L8CX::set_resolution(uint8_t resolution)
274 | {
275 | return vl53l8cx_set_resolution(p_dev, resolution);
276 | }
277 |
278 | /**
279 | * @brief Get the current ranging frequency of the VL53L8CX sensor in Hz.
280 | * @param p_frequency_hz Pointer to the variable that will be set to the current ranging frequency.
281 | * @return Status 0 if the ranging frequency is retrieved successfully.
282 | */
283 | uint8_t VL53L8CX::get_ranging_frequency_hz(uint8_t *p_frequency_hz)
284 | {
285 | return vl53l8cx_get_ranging_frequency_hz(p_dev, p_frequency_hz);
286 | }
287 |
288 | /**
289 | * @brief Set a new ranging frequency for the VL53L8CX sensor in Hz.
290 | * @param frequency_hz The new ranging frequency to be set.
291 | * @return Status 0 if the ranging frequency is set successfully, or 127 if the value is not correct.
292 | */
293 | uint8_t VL53L8CX::set_ranging_frequency_hz(uint8_t frequency_hz)
294 | {
295 | return vl53l8cx_set_ranging_frequency_hz(p_dev, frequency_hz);
296 | }
297 |
298 | /**
299 | * @brief Get the current integration time of the VL53L8CX sensor in ms.
300 | * @param p_time_ms Pointer to the variable that will be set to the current integration time.
301 | * @return Status 0 if the integration time is retrieved successfully.
302 | */
303 | uint8_t VL53L8CX::get_integration_time_ms(uint32_t *p_time_ms)
304 | {
305 | return vl53l8cx_get_integration_time_ms(p_dev, p_time_ms);
306 | }
307 |
308 | /**
309 | * @brief Set a new integration time for the VL53L8CX sensor in ms.
310 | * @param integration_time_ms The new integration time to be set.
311 | * @return Status 0 if the integration time is set successfully.
312 | */
313 | uint8_t VL53L8CX::set_integration_time_ms(uint32_t integration_time_ms)
314 | {
315 | return vl53l8cx_set_integration_time_ms(p_dev, integration_time_ms);
316 | }
317 |
318 | /**
319 | * @brief Get the current sharpener percentage of the VL53L8CX sensor.
320 | * @param p_sharpener_percent Pointer to the variable that will be set to the current sharpener percentage.
321 | * @return Status 0 if the sharpener percentage is retrieved successfully.
322 | */
323 | uint8_t VL53L8CX::get_sharpener_percent(uint8_t *p_sharpener_percent)
324 | {
325 | return vl53l8cx_get_sharpener_percent(p_dev, p_sharpener_percent);
326 | }
327 |
328 | /**
329 | * @brief Set a new sharpener percentage for the VL53L8CX sensor.
330 | * @param sharpener_percent The new sharpener percentage to be set.
331 | * @return Status 0 if the sharpener percentage is set successfully.
332 | */
333 | uint8_t VL53L8CX::set_sharpener_percent(uint8_t sharpener_percent)
334 | {
335 | return vl53l8cx_set_sharpener_percent(p_dev, sharpener_percent);
336 | }
337 | /**
338 | * @brief Get the current target order of the VL53L8CX sensor(closest or strongest).
339 | * @param p_target_order Pointer to the variable that will be set to the current target order.
340 | * @return Status 0 if the target order is retrieved successfully.
341 | */
342 | uint8_t VL53L8CX::get_target_order(uint8_t *p_target_order)
343 | {
344 | return vl53l8cx_get_target_order(p_dev, p_target_order);
345 | }
346 |
347 | /**
348 | * @brief Set a new target order for the VL53L8CX sensor.
349 | * @param target_order The new target order to be set.
350 | * @return Status 0 if the target order is set successfully, or 127 if the target order is unknown.
351 | */
352 | uint8_t VL53L8CX::set_target_order(uint8_t target_order)
353 | {
354 | return vl53l8cx_set_target_order(p_dev, target_order);
355 | }
356 |
357 | /**
358 | * @brief Get the current ranging mode of the VL53L8CX sensor.
359 | * @param p_ranging_mode Pointer to the variable that will be set to the current ranging mode.
360 | * @return Status 0 if the ranging mode is retrieved successfully.
361 | */
362 | uint8_t VL53L8CX::get_ranging_mode(uint8_t *p_ranging_mode)
363 | {
364 | return vl53l8cx_get_ranging_mode(p_dev, p_ranging_mode);
365 | }
366 |
367 | /**
368 | * @brief Set the ranging mode of the VL53L8CX sensor.
369 | * @param ranging_mode The new ranging mode to be set.
370 | * @return Status 0 if the ranging mode is set successfully.
371 | */
372 | uint8_t VL53L8CX::set_ranging_mode(uint8_t ranging_mode)
373 | {
374 | return vl53l8cx_set_ranging_mode(p_dev, ranging_mode);
375 | }
376 |
377 | /**
378 | * @brief Check if the synchronization pin of the VL53L8CX sensor is enabled.
379 | * @param p_is_sync_pin_enabled Pointer to the variable that will be updated to indicate if the sync pin is enabled.
380 | * @return Status 0 if the sync pin status is retrieved successfully.
381 | */
382 | uint8_t VL53L8CX::get_external_sync_pin_enable(uint8_t *p_is_sync_pin_enabled)
383 | {
384 | return vl53l8cx_get_external_sync_pin_enable(p_dev, p_is_sync_pin_enabled);
385 | }
386 |
387 | /**
388 | * @brief Enable or disable the synchronization pin of the VL53L8CX sensor.
389 | * @param enable_sync_pin Set to 1 to enable the sync pin, or 0 to disable it.
390 | * @return Status 0 if the sync pin is set successfully.
391 | */
392 | uint8_t VL53L8CX::set_external_sync_pin_enable(uint8_t enable_sync_pin)
393 | {
394 | return vl53l8cx_set_external_sync_pin_enable(p_dev, enable_sync_pin);
395 | }
396 |
397 | /**
398 | * @brief Get the number of frames between two temperature compensations for the VL53L8CX sensor.
399 | * @param p_repeat_count Pointer to the variable that will be set to the number of frames before the next temperature compensation.
400 | * @return Status 0 if the repeat count is retrieved successfully.
401 | */
402 | uint8_t VL53L8CX::get_VHV_repeat_count(uint32_t *p_repeat_count)
403 | {
404 | return vl53l8cx_get_VHV_repeat_count(p_dev, p_repeat_count);
405 | }
406 |
407 |
408 | /**
409 | * @brief Set the number of frames between two temperature compensations for the VL53L8CX sensor.
410 | * @param repeat_count The number of frames between temperature compensations to be set.
411 | * @return Status 0 if the repeat count is set successfully.
412 | */
413 | uint8_t VL53L8CX::set_VHV_repeat_count(uint32_t repeat_count)
414 | {
415 | return vl53l8cx_set_VHV_repeat_count(p_dev, repeat_count);
416 | }
417 |
418 | /**
419 | * @brief Read 'extra data' from the VL53L8CX sensor using DCI(Device Configuration Interface).
420 | * @param data Pointer to the data array or casted structure where the read data will be stored.
421 | * @param index Index of the required value to be read.
422 | * @param data_size Size of the data array or casted structure(use sizeof() function).
423 | * @return Status 0 if the read operation is successful.
424 | */
425 | uint8_t VL53L8CX::dci_read_data(uint8_t *data, uint32_t index, uint16_t data_size)
426 | {
427 | return vl53l8cx_dci_read_data(p_dev, data, index, data_size);
428 | }
429 |
430 | /**
431 | * @brief Write 'extra data' to the VL53L8CX sensor using DCI(Device Configuration Interface).
432 | * @param data Pointer to the data array or casted structure containing the data to be written.
433 | * @param index Index of the required value to be written.
434 | * @param data_size Size of the data array or casted structure(use sizeof() function).
435 | * @return Status 0 if the write operation is successful.
436 | */
437 | uint8_t VL53L8CX::dci_write_data(uint8_t *data, uint32_t index, uint16_t data_size)
438 | {
439 | return vl53l8cx_dci_write_data(p_dev, data, index, data_size);
440 | }
441 |
442 | /**
443 | * @brief Replace 'extra data' in the VL53L8CX sensor using DCI(Device Configuration Interface).
444 | * @param data Pointer to the data array or casted structure where the current data is stored.
445 | * @param index Index of the required value to be replaced.
446 | * @param data_size Size of the data array or casted structure(use sizeof() function).
447 | * @param new_data Pointer to the new data array containing the fields to be replaced.
448 | * @param new_data_size Size of the new data array.
449 | * @param new_data_pos Position of the new data in the buffer.
450 | * @return Status 0 if the replace operation is successful.
451 | */
452 | uint8_t VL53L8CX::dci_replace_data(uint8_t *data, uint32_t index, uint16_t data_size, uint8_t *new_data, uint16_t new_data_size, uint16_t new_data_pos)
453 | {
454 | return vl53l8cx_dci_replace_data(p_dev,
455 | data,
456 | index,
457 | data_size,
458 | new_data,
459 | new_data_size,
460 | new_data_pos);
461 | }
462 |
463 |
464 | /**
465 | * @brief Check if the detection thresholds are enabled on the VL53L8CX sensor.
466 | * @param p_enabled Pointer to the variable that will be set to 1 if thresholds are enabled, or 0 if disabled.
467 | * @return Status 0 if the check is successful.
468 | */
469 | uint8_t VL53L8CX::get_detection_thresholds_enable(uint8_t *p_enabled)
470 | {
471 | return vl53l8cx_get_detection_thresholds_enable(p_dev, p_enabled);
472 | }
473 |
474 | /**
475 | * @brief Enable or disable the detection thresholds on the VL53L8CX sensor.
476 | * @param enabled Set to 1 to enable thresholds, or 0 to disable them.
477 | * @return Status 0 if the thresholds are set successfully.
478 | */
479 | uint8_t VL53L8CX::set_detection_thresholds_enable(uint8_t enabled)
480 | {
481 | return vl53l8cx_set_detection_thresholds_enable(p_dev, enabled);
482 | }
483 |
484 | /**
485 | * @brief Get the detection thresholds from the VL53L8CX sensor.
486 | * @param p_thresholds Pointer to the array where the detection thresholds will be stored.
487 | * @return Status 0 if the thresholds are retrieved successfully.
488 | */
489 | uint8_t VL53L8CX::get_detection_thresholds(VL53L8CX_DetectionThresholds *p_thresholds)
490 | {
491 | return vl53l8cx_get_detection_thresholds(p_dev, p_thresholds);
492 | }
493 |
494 | /**
495 | * @brief Set the detection thresholds on the VL53L8CX sensor.
496 | * @param p_thresholds Pointer to the array containing the new detection thresholds.
497 | * @return Status 0 if the thresholds are programmed successfully.
498 | */
499 | uint8_t VL53L8CX::set_detection_thresholds(VL53L8CX_DetectionThresholds *p_thresholds)
500 | {
501 | return vl53l8cx_set_detection_thresholds(p_dev, p_thresholds);
502 | }
503 |
504 | /**
505 | * @brief Get the status of the auto-stop feature on the VL53L8CX sensor when using detection thresholds.
506 | * @param p_auto_stop Pointer to the variable that will be set to 1 if auto-stop is enabled, or 0 if disabled.
507 | * @return Status 0 if the auto-stop status is retrieved successfully.
508 | */
509 | uint8_t VL53L8CX::get_detection_thresholds_auto_stop(uint8_t *p_auto_stop)
510 | {
511 | return vl53l8cx_get_detection_thresholds_auto_stop(p_dev, p_auto_stop);
512 | }
513 |
514 | /**
515 | * @brief Enable or disable the auto-stop feature on the VL53L8CX sensor when using detection thresholds.
516 | * @param auto_stop Set to 1 to enable auto-stop, or 0 to disable it.
517 | * @return Status 0 if the auto-stop feature is set successfully.
518 | */
519 | uint8_t VL53L8CX::set_detection_thresholds_auto_stop(uint8_t auto_stop)
520 | {
521 | return vl53l8cx_set_detection_thresholds_auto_stop(p_dev, auto_stop);
522 | }
523 |
524 |
525 | /**
526 | * @brief Initialize the motion indicator with the default monitoring range.
527 | * @param p_motion_config Pointer to the structure containing the initialized motion configuration.
528 | * @param resolution The desired resolution, defined by macros VL53L8CX_RESOLUTION_4X4 or VL53L8CX_RESOLUTION_8X8.
529 | * @return Status 0 if initialization is successful, or 127 if the resolution is unknown.
530 | */
531 | uint8_t VL53L8CX::motion_indicator_init(VL53L8CX_Motion_Configuration *p_motion_config, uint8_t resolution)
532 | {
533 | return vl53l8cx_motion_indicator_init(p_dev, p_motion_config, resolution);
534 | }
535 |
536 | /**
537 | * @brief Change the working distance range of the motion indicator.
538 | * @param p_motion_config Pointer to the structure containing the motion configuration.
539 | * @param distance_min_mm Minimum distance for the motion indicator(minimum value 400mm, maximum 4000mm).
540 | * @param distance_max_mm Maximum distance for the motion indicator(minimum value 400mm, maximum 4000mm).
541 | * @return Status 0 if the configuration is successful, or 127 if an argument is invalid.
542 | */
543 | uint8_t VL53L8CX::motion_indicator_set_distance_motion(VL53L8CX_Motion_Configuration *p_motion_config, uint16_t distance_min_mm, uint16_t distance_max_mm)
544 | {
545 | return vl53l8cx_motion_indicator_set_distance_motion(p_dev, p_motion_config, distance_min_mm, distance_max_mm);
546 | }
547 |
548 | /**
549 | * @brief Update the internal motion indicator map to a new resolution.
550 | * @param p_motion_config Pointer to the structure containing the motion configuration.
551 | * @param resolution The desired SCI resolution, defined by macros VL53L8CX_RESOLUTION_4X4 or VL53L8CX_RESOLUTION_8X8.
552 | * @return Status 0 if the update is successful, or 127 if the resolution is unknown.
553 | */
554 | uint8_t VL53L8CX::motion_indicator_set_resolution(VL53L8CX_Motion_Configuration *p_motion_config, uint8_t resolution)
555 | {
556 | return vl53l8cx_motion_indicator_set_resolution(p_dev, p_motion_config, resolution);
557 | }
558 |
559 | /**
560 | * @brief Start the VL53L8CX sensor to calibrate Xtalk, recommended for use with a coverglass.
561 | * @param reflectance_percent Target reflectance in percent, between 1 and 99%. ST recommends a 3% target reflectance for better efficiency.
562 | * @param nb_samples Number of samples used for calibration. More samples increase accuracy but also calibration time. Minimum is 1, maximum is 16.
563 | * @param distance_mm Target distance in mm for calibration. Minimum allowed is 600mm, maximum is 3000mm. The target must stay in Full FOV.
564 | * @return Status 0 if calibration is successful, 127 if an argument has an incorrect value, or 255 if something failed.
565 | */
566 | uint8_t VL53L8CX::calibrate_xtalk(uint16_t reflectance_percent, uint8_t nb_samples, uint16_t distance_mm)
567 | {
568 | return vl53l8cx_calibrate_xtalk(p_dev, reflectance_percent, nb_samples, distance_mm);
569 | }
570 |
571 | /**
572 | * @brief Get the Xtalk calibration data buffer, available after using vl53l8cx_calibrate_xtalk().
573 | * @param p_xtalk_data Buffer to store Xtalk data, size defined by VL53L8CX_XTALK_SIZE macro.
574 | * @return Status 0 if buffer reading is successful.
575 | */
576 | uint8_t VL53L8CX::get_caldata_xtalk(uint8_t *p_xtalk_data)
577 | {
578 | return vl53l8cx_get_caldata_xtalk(p_dev, p_xtalk_data);
579 | }
580 |
581 | /**
582 | * @brief Set the Xtalk calibration data buffer, can be used to override the default Xtalk buffer.
583 | * @param p_xtalk_data Buffer containing Xtalk data, size defined by VL53L8CX_XTALK_SIZE macro.
584 | * @return Status 0 if buffer is set successfully.
585 | */
586 | uint8_t VL53L8CX::set_caldata_xtalk(uint8_t *p_xtalk_data)
587 | {
588 | return vl53l8cx_set_caldata_xtalk(p_dev, p_xtalk_data);
589 | }
590 |
591 | /**
592 | * @brief Get the Xtalk margin, used to increase the Xtalk threshold and avoid false positives after calibration.
593 | * @param p_xtalk_margin Pointer to store the current Xtalk margin in kcps/spads.
594 | * @return Status 0 if reading is successful.
595 | */
596 | uint8_t VL53L8CX::get_xtalk_margin(uint32_t *p_xtalk_margin)
597 | {
598 | return vl53l8cx_get_xtalk_margin(p_dev, p_xtalk_margin);
599 | }
600 |
601 | /**
602 | * @brief Set the Xtalk margin, used to increase the Xtalk threshold and avoid false positives after calibration.
603 | * @param xtalk_margin New Xtalk margin in kcps/spads. Minimum value is 0, maximum is 10,000 kcps/spads.
604 | * @return Status 0 if the new margin is set successfully, or 127 if the margin is invalid.
605 | */
606 | uint8_t VL53L8CX::set_xtalk_margin(uint32_t xtalk_margin)
607 | {
608 | return vl53l8cx_set_xtalk_margin(p_dev, xtalk_margin);
609 | }
610 |
611 | uint8_t VL53L8CX_io_write(void *handle, uint16_t RegisterAddress, uint8_t *p_values, uint32_t size)
612 | {
613 | return ((VL53L8CX *)handle)->IO_Write(RegisterAddress, p_values, size);
614 | }
615 |
616 | uint8_t VL53L8CX_io_read(void *handle, uint16_t RegisterAddress, uint8_t *p_values, uint32_t size)
617 | {
618 | return ((VL53L8CX *)handle)->IO_Read(RegisterAddress, p_values, size);
619 | }
620 |
621 | uint8_t VL53L8CX_io_wait(void *handle, uint32_t ms)
622 | {
623 | return ((VL53L8CX *)handle)->IO_Wait(ms);
624 | }
625 |
--------------------------------------------------------------------------------
/src/vl53l8cx.h:
--------------------------------------------------------------------------------
1 | /**
2 | ******************************************************************************
3 | * @file vl53l8cx.h
4 | * @author STMicroelectronics
5 | * @version V2.0.0
6 | * @date 27 June 2024
7 | * @brief Abstract class of a VL53L8CX Time of Flight(TOF) sensor.
8 | ******************************************************************************
9 | * @attention
10 | *
11 | * © COPYRIGHT(c) 2024 STMicroelectronics
12 | *
13 | * Redistribution and use in source and binary forms, with or without modification,
14 | * are permitted provided that the following conditions are met:
15 | * 1. Redistributions of source code must retain the above copyright notice,
16 | * this list of conditions and the following disclaimer.
17 | * 2. Redistributions in binary form must reproduce the above copyright notice,
18 | * this list of conditions and the following disclaimer in the documentation
19 | * and/or other materials provided with the distribution.
20 | * 3. Neither the name of STMicroelectronics nor the names of its contributors
21 | * may be used to endorse or promote products derived from this software
22 | * without specific prior written permission.
23 | *
24 | * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
25 | * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
26 | * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
27 | * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
28 | * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
29 | * DAMAGES(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
30 | * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
31 | * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
32 | * OR TORT(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
33 | * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
34 | *
35 | ******************************************************************************
36 | */
37 |
38 | /* Prevent recursive inclusion -----------------------------------------------*/
39 | #ifndef __VL53L8CX_H
40 | #define __VL53L8CX_H
41 |
42 | /* Includes ------------------------------------------------------------------*/
43 | #include "Arduino.h"
44 | #include "Wire.h"
45 | #include "SPI.h"
46 | #include "vl53l8cx_platform.h"
47 | #include "vl53l8cx_api.h"
48 | #include "vl53l8cx_plugin_detection_thresholds.h"
49 | #include "vl53l8cx_plugin_motion_indicator.h"
50 | #include "vl53l8cx_plugin_xtalk.h"
51 |
52 | /* Class Declaration ---------------------------------------------------------*/
53 | class VL53L8CX {
54 | public:
55 | VL53L8CX(TwoWire *i2c, int lpn_pin, int i2c_rst_pin = -1);
56 | VL53L8CX(SPIClass *spi, int cs_pin, int lpn_pin = -1, int i2c_rst_pin = -1, uint32_t spi_speed = 5000000);
57 | virtual ~VL53L8CX(void);
58 | virtual int begin(void);
59 | virtual int end(void);
60 | virtual void on(void);
61 | virtual void off(void);
62 | virtual void i2c_reset(void);
63 | uint8_t is_alive(uint8_t *p_is_alive);
64 | uint8_t init(void);
65 | uint8_t set_i2c_address(uint16_t i2c_address);
66 | uint8_t get_power_mode(uint8_t *p_power_mode);
67 | uint8_t set_power_mode(uint8_t power_mode);
68 | uint8_t start_ranging(void);
69 | uint8_t stop_ranging(void);
70 | uint8_t check_data_ready(uint8_t *p_isReady);
71 | uint8_t get_ranging_data(VL53L8CX_ResultsData *p_results);
72 | uint8_t get_resolution(uint8_t *p_resolution);
73 | uint8_t set_resolution(uint8_t resolution);
74 | uint8_t get_ranging_frequency_hz(uint8_t *p_frequency_hz);
75 | uint8_t set_ranging_frequency_hz(uint8_t frequency_hz);
76 | uint8_t get_integration_time_ms(uint32_t *p_time_ms);
77 | uint8_t set_integration_time_ms(uint32_t integration_time_ms);
78 | uint8_t get_sharpener_percent(uint8_t *p_sharpener_percent);
79 | uint8_t set_sharpener_percent(uint8_t sharpener_percent);
80 | uint8_t get_target_order(uint8_t *p_target_order);
81 | uint8_t set_target_order(uint8_t target_order);
82 | uint8_t get_ranging_mode(uint8_t *p_ranging_mode);
83 | uint8_t set_ranging_mode(uint8_t ranging_mode);
84 | uint8_t get_external_sync_pin_enable(uint8_t *p_is_sync_pin_enabled);
85 | uint8_t set_external_sync_pin_enable(uint8_t enable_sync_pin);
86 | uint8_t get_VHV_repeat_count(uint32_t *p_repeat_count);
87 | uint8_t set_VHV_repeat_count(uint32_t repeat_count);
88 | uint8_t dci_read_data(uint8_t *data, uint32_t index, uint16_t data_size);
89 | uint8_t dci_write_data(uint8_t *data, uint32_t index, uint16_t data_size);
90 | uint8_t dci_replace_data(uint8_t *data, uint32_t index, uint16_t data_size, uint8_t *new_data, uint16_t new_data_size, uint16_t new_data_pos);
91 | uint8_t get_detection_thresholds_enable(uint8_t *p_enabled);
92 | uint8_t set_detection_thresholds_enable(uint8_t enabled);
93 | uint8_t get_detection_thresholds(VL53L8CX_DetectionThresholds *p_thresholds);
94 | uint8_t set_detection_thresholds(VL53L8CX_DetectionThresholds *p_thresholds);
95 | uint8_t get_detection_thresholds_auto_stop(uint8_t *p_auto_stop);
96 | uint8_t set_detection_thresholds_auto_stop(uint8_t auto_stop);
97 | uint8_t motion_indicator_init(VL53L8CX_Motion_Configuration *p_motion_config, uint8_t resolution);
98 | uint8_t motion_indicator_set_distance_motion(VL53L8CX_Motion_Configuration *p_motion_config, uint16_t distance_min_mm, uint16_t distance_max_mm);
99 | uint8_t motion_indicator_set_resolution(VL53L8CX_Motion_Configuration *p_motion_config, uint8_t resolution);
100 | uint8_t calibrate_xtalk(uint16_t reflectance_percent, uint8_t nb_samples, uint16_t distance_mm);
101 | uint8_t get_caldata_xtalk(uint8_t *p_xtalk_data);
102 | uint8_t set_caldata_xtalk(uint8_t *p_xtalk_data);
103 | uint8_t get_xtalk_margin(uint32_t *p_xtalk_margin);
104 | uint8_t set_xtalk_margin(uint32_t xtalk_margin);
105 |
106 | /**
107 | * @brief Utility function to read data.
108 | * @param RegisterAddr: specifies internal address register to be read.
109 | * @param p_values: pointer to data to be read.
110 | * @param size: number of bytes to be read.
111 | * @retval 0 if ok, an error code otherwise.
112 | */
113 | uint8_t IO_Read(uint16_t RegisterAddress, uint8_t *p_values, uint32_t size)
114 | {
115 | if (dev_i2c) {
116 | int status = 0;
117 | uint8_t buffer[2];
118 | // Loop until the port is transmitted correctly
119 | do {
120 | dev_i2c->beginTransmission((uint8_t)((_dev.platform.address >> 1) & 0x7F));
121 | // Target register address for transfer
122 | buffer[0] = (uint8_t)(RegisterAddress >> 8);
123 | buffer[1] = (uint8_t)(RegisterAddress & 0xFF);
124 | dev_i2c->write(buffer, 2);
125 | status = dev_i2c->endTransmission(false);
126 | // Fix for some STM32 boards
127 | // Reinitialize the i2c bus with the default parameters
128 | #ifdef ARDUINO_ARCH_STM32
129 | if (status) {
130 | dev_i2c->end();
131 | dev_i2c->begin();
132 | }
133 | #endif
134 | // End of fix
135 | } while (status != 0);
136 | uint32_t i = 0;
137 | if (size > DEFAULT_I2C_BUFFER_LEN) {
138 | while (i < size) {
139 | // If still more than DEFAULT_I2C_BUFFER_LEN bytes to go, DEFAULT_I2C_BUFFER_LEN,
140 | // else the remaining number of bytes
141 | uint8_t current_read_size = (size - i > DEFAULT_I2C_BUFFER_LEN ? DEFAULT_I2C_BUFFER_LEN : size - i);
142 | dev_i2c->requestFrom(((uint8_t)((_dev.platform.address >> 1) & 0x7F)), current_read_size);
143 | while (dev_i2c->available()) {
144 | p_values[i] = dev_i2c->read();
145 | i++;
146 | }
147 | }
148 | } else {
149 | dev_i2c->requestFrom(((uint8_t)((_dev.platform.address >> 1) & 0x7F)), size);
150 | while (dev_i2c->available()) {
151 | p_values[i] = dev_i2c->read();
152 | i++;
153 | }
154 | }
155 | return i != size;
156 | }
157 | if (dev_spi) {
158 | uint32_t position = 0;
159 | uint32_t data_size = 0;
160 | uint16_t temp;
161 | uint8_t data_write[VL53L8CX_COMMS_CHUNK_SIZE + 2];
162 | for (position = 0; position < size; position += VL53L8CX_COMMS_CHUNK_SIZE) {
163 | if (size > VL53L8CX_COMMS_CHUNK_SIZE) {
164 | if ((position + VL53L8CX_COMMS_CHUNK_SIZE) > size) {
165 | data_size = size - position;
166 | } else {
167 | data_size = VL53L8CX_COMMS_CHUNK_SIZE;
168 | }
169 | } else {
170 | data_size = size;
171 | }
172 | temp = RegisterAddress + position;
173 | data_write[0] = SPI_READ_MASK(temp) >> 8;
174 | data_write[1] = SPI_READ_MASK(temp) & 0xFF;
175 | dev_spi->beginTransaction(SPISettings(spi_speed, MSBFIRST, SPI_MODE3));
176 | digitalWrite(cs_pin, LOW);
177 | dev_spi->transfer(&data_write, 2);
178 | for (uint16_t i = 0; i < data_size; i++) {
179 | *(p_values + i + position) = dev_spi->transfer(0x00);
180 | }
181 | digitalWrite(cs_pin, HIGH);
182 | }
183 | return 0;
184 | }
185 | return 1;
186 | }
187 |
188 | /**
189 | * @brief Utility function to write data.
190 | * @param RegisterAddr: specifies internal address register to be written.
191 | * @param p_values: pointer to data to be written.
192 | * @param size: number of bytes to be written.
193 | * @retval 0 if ok, an error code otherwise.
194 | */
195 | uint8_t IO_Write(uint16_t RegisterAddress, uint8_t *p_values, uint32_t size)
196 | {
197 | if (dev_i2c) {
198 | uint32_t i = 0;
199 | uint8_t buffer[2];
200 | while (i < size) {
201 | // If still more than DEFAULT_I2C_BUFFER_LEN bytes to go, DEFAULT_I2C_BUFFER_LEN,
202 | // else the remaining number of bytes
203 | size_t current_write_size = (size - i > DEFAULT_I2C_BUFFER_LEN ? DEFAULT_I2C_BUFFER_LEN : size - i);
204 | dev_i2c->beginTransmission((uint8_t)((_dev.platform.address >> 1) & 0x7F));
205 | // Target register address for transfer
206 | buffer[0] = (uint8_t)((RegisterAddress + i) >> 8);
207 | buffer[1] = (uint8_t)((RegisterAddress + i) & 0xFF);
208 | dev_i2c->write(buffer, 2);
209 | if (dev_i2c->write(p_values + i, current_write_size) == 0) {
210 | return 1;
211 | } else {
212 | i += current_write_size;
213 | if (size - i) {
214 | // Flush buffer and send stop bit so we have compatibility also with ESP32 platforms
215 | dev_i2c->endTransmission(true);
216 | }
217 | }
218 | }
219 | return dev_i2c->endTransmission(true);
220 | }
221 |
222 | if (dev_spi) {
223 |
224 | uint8_t status = 0;
225 | uint32_t i = 0;
226 | uint32_t position = 0;
227 | uint32_t data_size = 0;
228 | uint16_t temp;
229 | uint8_t data_write[VL53L8CX_COMMS_CHUNK_SIZE + 2];
230 | for (position = 0; position < size; position += VL53L8CX_COMMS_CHUNK_SIZE) {
231 | if (size > VL53L8CX_COMMS_CHUNK_SIZE) {
232 | if ((position + VL53L8CX_COMMS_CHUNK_SIZE) > size) {
233 | data_size = size - position;
234 | } else {
235 | data_size = VL53L8CX_COMMS_CHUNK_SIZE;
236 | }
237 | } else {
238 | data_size = size;
239 | }
240 | temp = RegisterAddress + position;
241 | data_write[0] = SPI_WRITE_MASK(temp) >> 8;
242 | data_write[1] = SPI_WRITE_MASK(temp) & 0xFF;
243 | for (i = 0; i < data_size; i++) {
244 | data_write[i + 2] = p_values[position + i];
245 | }
246 | data_size += 2;
247 | dev_spi->beginTransaction(SPISettings(spi_speed, MSBFIRST, SPI_MODE3));
248 | digitalWrite(cs_pin, LOW);
249 | dev_spi->transfer(&data_write, data_size);
250 | digitalWrite(cs_pin, HIGH);
251 | }
252 | return status;
253 | }
254 | return 1;
255 | }
256 |
257 | /**
258 | * @brief Utility function to wait.
259 | * @param ms: milliseconds to wait.
260 | * @retval 0
261 | */
262 | uint8_t IO_Wait(uint32_t ms)
263 | {
264 | delay(ms);
265 | return 0;
266 | }
267 |
268 | private:
269 |
270 | /* Helper classes. */
271 | TwoWire *dev_i2c;
272 | SPIClass *dev_spi;
273 |
274 | /* Configuration */
275 | int cs_pin;
276 | int lpn_pin;
277 | int i2c_rst_pin;
278 | uint32_t spi_speed;
279 |
280 | VL53L8CX_Configuration _dev;
281 | VL53L8CX_Configuration *p_dev;
282 | };
283 |
284 |
285 | #ifdef __cplusplus
286 | extern "C" {
287 | #endif
288 |
289 | uint8_t VL53L8CX_io_write(void *handle, uint16_t RegisterAddress, uint8_t *p_values, uint32_t size);
290 | uint8_t VL53L8CX_io_read(void *handle, uint16_t RegisterAddress, uint8_t *p_values, uint32_t size);
291 | uint8_t VL53L8CX_io_wait(void *handle, uint32_t ms);
292 |
293 | #ifdef __cplusplus
294 | }
295 | #endif
296 |
297 | #endif /* __VL53L8CX_H */
298 |
--------------------------------------------------------------------------------
/src/vl53l8cx_api.c:
--------------------------------------------------------------------------------
1 | /**
2 | *
3 | * Copyright (c) 2021 STMicroelectronics.
4 | * All rights reserved.
5 | *
6 | * This software is licensed under terms that can be found in the LICENSE file
7 | * in the root directory of this software component.
8 | * If no LICENSE file comes with this software, it is provided AS-IS.
9 | *
10 | ******************************************************************************
11 | */
12 |
13 | #include
14 | #include
15 | #include "vl53l8cx_api.h"
16 | #include "vl53l8cx_buffers.h"
17 |
18 | /**
19 | * @brief Inner function, not available outside this file. This function is used
20 | * to wait for an answer from VL53L8CX sensor.
21 | */
22 |
23 | static uint8_t _vl53l8cx_poll_for_answer(
24 | VL53L8CX_Configuration *p_dev,
25 | uint8_t size,
26 | uint8_t pos,
27 | uint16_t address,
28 | uint8_t mask,
29 | uint8_t expected_value)
30 | {
31 | uint8_t status = VL53L8CX_STATUS_OK;
32 | uint8_t timeout = 0;
33 |
34 | do {
35 | status |= VL53L8CX_RdMulti(&(p_dev->platform), address,
36 | p_dev->temp_buffer, size);
37 | status |= VL53L8CX_WaitMs(&(p_dev->platform), 10);
38 |
39 | if (timeout >= (uint8_t)200) { /* 2s timeout */
40 | status |= (uint8_t)VL53L8CX_STATUS_TIMEOUT_ERROR;
41 | break;
42 | } else if ((size >= (uint8_t)4)
43 | && (p_dev->temp_buffer[2] >= (uint8_t)0x7f)) {
44 | status |= VL53L8CX_MCU_ERROR;
45 | break;
46 | } else {
47 | timeout++;
48 | }
49 | } while ((p_dev->temp_buffer[pos] & mask) != expected_value);
50 |
51 | return status;
52 | }
53 |
54 | /*
55 | * Inner function, not available outside this file. This function is used to
56 | * wait for the MCU to boot.
57 | */
58 | static uint8_t _vl53l8cx_poll_for_mcu_boot(
59 | VL53L8CX_Configuration *p_dev)
60 | {
61 | uint8_t go2_status0, go2_status1, status = VL53L8CX_STATUS_OK;
62 | uint16_t timeout = 0;
63 |
64 | do {
65 | status |= VL53L8CX_RdByte(&(p_dev->platform), 0x06, &go2_status0);
66 | if ((go2_status0 & (uint8_t)0x80) != (uint8_t)0) {
67 | status |= VL53L8CX_RdByte(&(p_dev->platform), 0x07, &go2_status1);
68 | if (go2_status1 & (uint8_t)0x01) {
69 | status |= VL53L8CX_STATUS_OK;
70 | break;
71 | }
72 | }
73 | (void)VL53L8CX_WaitMs(&(p_dev->platform), 1);
74 | timeout++;
75 |
76 | if ((go2_status0 & (uint8_t)0x1) != (uint8_t)0) {
77 | break;
78 | }
79 | } while (timeout < (uint16_t)500);
80 |
81 | return status;
82 | }
83 |
84 | /**
85 | * @brief Inner function, not available outside this file. This function is used
86 | * to set the offset data gathered from NVM.
87 | */
88 |
89 | static uint8_t _vl53l8cx_send_offset_data(
90 | VL53L8CX_Configuration *p_dev,
91 | uint8_t resolution)
92 | {
93 | uint8_t status = VL53L8CX_STATUS_OK;
94 | uint32_t signal_grid[64];
95 | int16_t range_grid[64];
96 | uint8_t dss_4x4[] = {0x0F, 0x04, 0x04, 0x00, 0x08, 0x10, 0x10, 0x07};
97 | uint8_t footer[] = {0x00, 0x00, 0x00, 0x0F, 0x03, 0x01, 0x01, 0xE4};
98 | int8_t i, j;
99 | uint16_t k;
100 |
101 | (void)memcpy(p_dev->temp_buffer,
102 | p_dev->offset_data, VL53L8CX_OFFSET_BUFFER_SIZE);
103 |
104 | /* Data extrapolation is required for 4X4 offset */
105 | if (resolution == (uint8_t)VL53L8CX_RESOLUTION_4X4) {
106 | (void)memcpy(&(p_dev->temp_buffer[0x10]), dss_4x4, sizeof(dss_4x4));
107 | VL53L8CX_SwapBuffer(p_dev->temp_buffer, VL53L8CX_OFFSET_BUFFER_SIZE);
108 | (void)memcpy(signal_grid, &(p_dev->temp_buffer[0x3C]),
109 | sizeof(signal_grid));
110 | (void)memcpy(range_grid, &(p_dev->temp_buffer[0x140]),
111 | sizeof(range_grid));
112 |
113 | for (j = 0; j < (int8_t)4; j++) {
114 | for (i = 0; i < (int8_t)4 ; i++) {
115 | signal_grid[i + (4 * j)] =
116 | (signal_grid[(2 * i) + (16 * j) + (int8_t)0]
117 | + signal_grid[(2 * i) + (16 * j) + (int8_t)1]
118 | + signal_grid[(2 * i) + (16 * j) + (int8_t)8]
119 | + signal_grid[(2 * i) + (16 * j) + (int8_t)9])
120 | / (uint32_t)4;
121 | range_grid[i + (4 * j)] =
122 | (range_grid[(2 * i) + (16 * j)]
123 | + range_grid[(2 * i) + (16 * j) + 1]
124 | + range_grid[(2 * i) + (16 * j) + 8]
125 | + range_grid[(2 * i) + (16 * j) + 9])
126 | / (int16_t)4;
127 | }
128 | }
129 | (void)memset(&range_grid[0x10], 0, (uint16_t)96);
130 | (void)memset(&signal_grid[0x10], 0, (uint16_t)192);
131 | (void)memcpy(&(p_dev->temp_buffer[0x3C]),
132 | signal_grid, sizeof(signal_grid));
133 | (void)memcpy(&(p_dev->temp_buffer[0x140]),
134 | range_grid, sizeof(range_grid));
135 | VL53L8CX_SwapBuffer(p_dev->temp_buffer, VL53L8CX_OFFSET_BUFFER_SIZE);
136 | }
137 |
138 | for (k = 0; k < (VL53L8CX_OFFSET_BUFFER_SIZE - (uint16_t)4); k++) {
139 | p_dev->temp_buffer[k] = p_dev->temp_buffer[k + (uint16_t)8];
140 | }
141 |
142 | (void)memcpy(&(p_dev->temp_buffer[0x1E0]), footer, 8);
143 | status |= VL53L8CX_WrMulti(&(p_dev->platform), 0x2e18, p_dev->temp_buffer,
144 | VL53L8CX_OFFSET_BUFFER_SIZE);
145 | status |= _vl53l8cx_poll_for_answer(p_dev, 4, 1,
146 | VL53L8CX_UI_CMD_STATUS, 0xff, 0x03);
147 |
148 | return status;
149 | }
150 |
151 | /**
152 | * @brief Inner function, not available outside this file. This function is used
153 | * to set the Xtalk data from generic configuration, or user's calibration.
154 | */
155 |
156 | static uint8_t _vl53l8cx_send_xtalk_data(
157 | VL53L8CX_Configuration *p_dev,
158 | uint8_t resolution)
159 | {
160 | uint8_t status = VL53L8CX_STATUS_OK;
161 | uint8_t res4x4[] = {0x0F, 0x04, 0x04, 0x17, 0x08, 0x10, 0x10, 0x07};
162 | uint8_t dss_4x4[] = {0x00, 0x78, 0x00, 0x08, 0x00, 0x00, 0x00, 0x08};
163 | uint8_t profile_4x4[] = {0xA0, 0xFC, 0x01, 0x00};
164 | uint32_t signal_grid[64];
165 | int8_t i, j;
166 |
167 | (void)memcpy(p_dev->temp_buffer, &(p_dev->xtalk_data[0]),
168 | VL53L8CX_XTALK_BUFFER_SIZE);
169 |
170 | /* Data extrapolation is required for 4X4 Xtalk */
171 | if (resolution == (uint8_t)VL53L8CX_RESOLUTION_4X4) {
172 | (void)memcpy(&(p_dev->temp_buffer[0x8]),
173 | res4x4, sizeof(res4x4));
174 | (void)memcpy(&(p_dev->temp_buffer[0x020]),
175 | dss_4x4, sizeof(dss_4x4));
176 |
177 | VL53L8CX_SwapBuffer(p_dev->temp_buffer, VL53L8CX_XTALK_BUFFER_SIZE);
178 | (void)memcpy(signal_grid, &(p_dev->temp_buffer[0x34]),
179 | sizeof(signal_grid));
180 |
181 | for (j = 0; j < (int8_t)4; j++) {
182 | for (i = 0; i < (int8_t)4 ; i++) {
183 | signal_grid[i + (4 * j)] =
184 | (signal_grid[(2 * i) + (16 * j) + 0]
185 | + signal_grid[(2 * i) + (16 * j) + 1]
186 | + signal_grid[(2 * i) + (16 * j) + 8]
187 | + signal_grid[(2 * i) + (16 * j) + 9]) / (uint32_t)4;
188 | }
189 | }
190 | (void)memset(&signal_grid[0x10], 0, (uint32_t)192);
191 | (void)memcpy(&(p_dev->temp_buffer[0x34]),
192 | signal_grid, sizeof(signal_grid));
193 | VL53L8CX_SwapBuffer(p_dev->temp_buffer, VL53L8CX_XTALK_BUFFER_SIZE);
194 | (void)memcpy(&(p_dev->temp_buffer[0x134]),
195 | profile_4x4, sizeof(profile_4x4));
196 | (void)memset(&(p_dev->temp_buffer[0x078]), 0,
197 | (uint32_t)4 * sizeof(uint8_t));
198 | }
199 |
200 | status |= VL53L8CX_WrMulti(&(p_dev->platform), 0x2cf8,
201 | p_dev->temp_buffer, VL53L8CX_XTALK_BUFFER_SIZE);
202 | status |= _vl53l8cx_poll_for_answer(p_dev, 4, 1,
203 | VL53L8CX_UI_CMD_STATUS, 0xff, 0x03);
204 |
205 | return status;
206 | }
207 |
208 | uint8_t vl53l8cx_is_alive(
209 | VL53L8CX_Configuration *p_dev,
210 | uint8_t *p_is_alive)
211 | {
212 | uint8_t status = VL53L8CX_STATUS_OK;
213 | uint8_t device_id, revision_id;
214 |
215 | status |= VL53L8CX_WrByte(&(p_dev->platform), 0x7fff, 0x00);
216 | status |= VL53L8CX_RdByte(&(p_dev->platform), 0, &device_id);
217 | status |= VL53L8CX_RdByte(&(p_dev->platform), 1, &revision_id);
218 | status |= VL53L8CX_WrByte(&(p_dev->platform), 0x7fff, 0x02);
219 |
220 |
221 | if ((device_id == (uint8_t)0xF0) && (revision_id == (uint8_t)0x0C)) {
222 | *p_is_alive = 1;
223 | } else {
224 | *p_is_alive = 0;
225 | }
226 |
227 |
228 | return status;
229 | }
230 |
231 | uint8_t vl53l8cx_init(
232 | VL53L8CX_Configuration *p_dev)
233 | {
234 | uint8_t tmp, status = VL53L8CX_STATUS_OK;
235 | uint8_t pipe_ctrl[] = {VL53L8CX_NB_TARGET_PER_ZONE, 0x00, 0x01, 0x00};
236 | uint32_t single_range = 0x01;
237 | uint32_t crc_checksum = 0x00;
238 | p_dev->default_xtalk = (uint8_t *)VL53L8CX_DEFAULT_XTALK;
239 | p_dev->default_configuration = (uint8_t *)VL53L8CX_DEFAULT_CONFIGURATION;
240 | p_dev->is_auto_stop_enabled = (uint8_t)0x0;
241 |
242 | /* SW reboot sequence */
243 | status |= VL53L8CX_WrByte(&(p_dev->platform), 0x7fff, 0x00);
244 | status |= VL53L8CX_WrByte(&(p_dev->platform), 0x0009, 0x04);
245 |
246 | status |= VL53L8CX_WrByte(&(p_dev->platform), 0x000F, 0x40);
247 | status |= VL53L8CX_WrByte(&(p_dev->platform), 0x000A, 0x03);
248 | status |= VL53L8CX_RdByte(&(p_dev->platform), 0x7FFF, &tmp);
249 | status |= VL53L8CX_WrByte(&(p_dev->platform), 0x000C, 0x01);
250 |
251 | status |= VL53L8CX_WrByte(&(p_dev->platform), 0x0101, 0x00);
252 | status |= VL53L8CX_WrByte(&(p_dev->platform), 0x0102, 0x00);
253 | status |= VL53L8CX_WrByte(&(p_dev->platform), 0x010A, 0x01);
254 | status |= VL53L8CX_WrByte(&(p_dev->platform), 0x4002, 0x01);
255 | status |= VL53L8CX_WrByte(&(p_dev->platform), 0x4002, 0x00);
256 | status |= VL53L8CX_WrByte(&(p_dev->platform), 0x010A, 0x03);
257 | status |= VL53L8CX_WrByte(&(p_dev->platform), 0x0103, 0x01);
258 | status |= VL53L8CX_WrByte(&(p_dev->platform), 0x000C, 0x00);
259 | status |= VL53L8CX_WrByte(&(p_dev->platform), 0x000F, 0x43);
260 | status |= VL53L8CX_WaitMs(&(p_dev->platform), 1);
261 | status |= VL53L8CX_WrByte(&(p_dev->platform), 0x000F, 0x40);
262 | status |= VL53L8CX_WrByte(&(p_dev->platform), 0x000A, 0x01);
263 |
264 | status |= VL53L8CX_WaitMs(&(p_dev->platform), 100);
265 | /* Wait for sensor booted (several ms required to get sensor ready ) */
266 | status |= VL53L8CX_WrByte(&(p_dev->platform), 0x7fff, 0x00);
267 | status |= _vl53l8cx_poll_for_answer(p_dev, 1, 0, 0x06, 0xff, 1);
268 | if (status != (uint8_t)0) {
269 | goto exit;
270 | }
271 |
272 | status |= VL53L8CX_WrByte(&(p_dev->platform), 0x000E, 0x01);
273 | status |= VL53L8CX_WrByte(&(p_dev->platform), 0x7fff, 0x02);
274 |
275 | /* Enable FW access */
276 | status |= VL53L8CX_WrByte(&(p_dev->platform), 0x7fff, 0x01);
277 | status |= VL53L8CX_WrByte(&(p_dev->platform), 0x06, 0x01);
278 | status |= _vl53l8cx_poll_for_answer(p_dev, 1, 0, 0x21, 0xFF, 0x4);
279 |
280 | status |= VL53L8CX_WrByte(&(p_dev->platform), 0x7fff, 0x00);
281 |
282 | /* Enable host access to GO1 */
283 | status |= VL53L8CX_RdByte(&(p_dev->platform), 0x7fff, &tmp);
284 | status |= VL53L8CX_WrByte(&(p_dev->platform), 0x0C, 0x01);
285 |
286 | /* Power ON status */
287 | status |= VL53L8CX_WrByte(&(p_dev->platform), 0x7fff, 0x00);
288 | status |= VL53L8CX_WrByte(&(p_dev->platform), 0x101, 0x00);
289 | status |= VL53L8CX_WrByte(&(p_dev->platform), 0x102, 0x00);
290 | status |= VL53L8CX_WrByte(&(p_dev->platform), 0x010A, 0x01);
291 | status |= VL53L8CX_WrByte(&(p_dev->platform), 0x4002, 0x01);
292 | status |= VL53L8CX_WrByte(&(p_dev->platform), 0x4002, 0x00);
293 | status |= VL53L8CX_WrByte(&(p_dev->platform), 0x010A, 0x03);
294 | status |= VL53L8CX_WrByte(&(p_dev->platform), 0x103, 0x01);
295 | status |= VL53L8CX_WrByte(&(p_dev->platform), 0x400F, 0x00);
296 | status |= VL53L8CX_WrByte(&(p_dev->platform), 0x21A, 0x43);
297 | status |= VL53L8CX_WrByte(&(p_dev->platform), 0x21A, 0x03);
298 | status |= VL53L8CX_WrByte(&(p_dev->platform), 0x21A, 0x01);
299 | status |= VL53L8CX_WrByte(&(p_dev->platform), 0x21A, 0x00);
300 | status |= VL53L8CX_WrByte(&(p_dev->platform), 0x219, 0x00);
301 | status |= VL53L8CX_WrByte(&(p_dev->platform), 0x21B, 0x00);
302 |
303 | /* Wake up MCU */
304 | status |= VL53L8CX_WrByte(&(p_dev->platform), 0x7fff, 0x00);
305 | status |= VL53L8CX_RdByte(&(p_dev->platform), 0x7fff, &tmp);
306 | status |= VL53L8CX_WrByte(&(p_dev->platform), 0x7fff, 0x01);
307 |
308 | /* Download FW into VL53L8CX */
309 | status |= VL53L8CX_WrByte(&(p_dev->platform), 0x7fff, 0x09);
310 | status |= VL53L8CX_WrMulti(&(p_dev->platform), 0,
311 | (uint8_t *)&VL53L8CX_FIRMWARE[0], 0x8000);
312 | status |= VL53L8CX_WrByte(&(p_dev->platform), 0x7fff, 0x0a);
313 | status |= VL53L8CX_WrMulti(&(p_dev->platform), 0,
314 | (uint8_t *)&VL53L8CX_FIRMWARE[0x8000], 0x8000);
315 | status |= VL53L8CX_WrByte(&(p_dev->platform), 0x7fff, 0x0b);
316 | status |= VL53L8CX_WrMulti(&(p_dev->platform), 0,
317 | (uint8_t *)&VL53L8CX_FIRMWARE[0x10000], 0x5000);
318 | status |= VL53L8CX_WrByte(&(p_dev->platform), 0x7fff, 0x01);
319 |
320 | /* Check if FW correctly downloaded */
321 | status |= VL53L8CX_WrByte(&(p_dev->platform), 0x7fff, 0x01);
322 | status |= VL53L8CX_WrByte(&(p_dev->platform), 0x06, 0x03);
323 |
324 | status |= VL53L8CX_WaitMs(&(p_dev->platform), 5);
325 | status |= VL53L8CX_WrByte(&(p_dev->platform), 0x7fff, 0x00);
326 | status |= VL53L8CX_RdByte(&(p_dev->platform), 0x7fff, &tmp);
327 | status |= VL53L8CX_WrByte(&(p_dev->platform), 0x0C, 0x01);
328 |
329 | /* Reset MCU and wait boot */
330 | status |= VL53L8CX_WrByte(&(p_dev->platform), 0x7FFF, 0x00);
331 | status |= VL53L8CX_WrByte(&(p_dev->platform), 0x114, 0x00);
332 | status |= VL53L8CX_WrByte(&(p_dev->platform), 0x115, 0x00);
333 | status |= VL53L8CX_WrByte(&(p_dev->platform), 0x116, 0x42);
334 | status |= VL53L8CX_WrByte(&(p_dev->platform), 0x117, 0x00);
335 | status |= VL53L8CX_WrByte(&(p_dev->platform), 0x0B, 0x00);
336 | status |= VL53L8CX_RdByte(&(p_dev->platform), 0x7fff, &tmp);
337 | status |= VL53L8CX_WrByte(&(p_dev->platform), 0x0C, 0x00);
338 | status |= VL53L8CX_WrByte(&(p_dev->platform), 0x0B, 0x01);
339 |
340 | status |= _vl53l8cx_poll_for_mcu_boot(p_dev);
341 | if (status != (uint8_t)0) {
342 | goto exit;
343 | }
344 |
345 | status |= VL53L8CX_WrByte(&(p_dev->platform), 0x7fff, 0x02);
346 |
347 | /* Firmware checksum */
348 | status |= VL53L8CX_RdMulti(&(p_dev->platform), (uint16_t)(0x812FFC & 0xFFFF),
349 | p_dev->temp_buffer, 4);
350 | VL53L8CX_SwapBuffer(p_dev->temp_buffer, 4);
351 | memcpy((uint8_t *)&crc_checksum, &(p_dev->temp_buffer[0]), 4);
352 | if (crc_checksum != (uint32_t)0xc0b6c9e) {
353 | status |= VL53L8CX_STATUS_FW_CHECKSUM_FAIL;
354 | goto exit;
355 | }
356 |
357 | /* Get offset NVM data and store them into the offset buffer */
358 | status |= VL53L8CX_WrMulti(&(p_dev->platform), 0x2fd8,
359 | (uint8_t *)VL53L8CX_GET_NVM_CMD, sizeof(VL53L8CX_GET_NVM_CMD));
360 | status |= _vl53l8cx_poll_for_answer(p_dev, 4, 0,
361 | VL53L8CX_UI_CMD_STATUS, 0xff, 2);
362 | status |= VL53L8CX_RdMulti(&(p_dev->platform), VL53L8CX_UI_CMD_START,
363 | p_dev->temp_buffer, VL53L8CX_NVM_DATA_SIZE);
364 | (void)memcpy(p_dev->offset_data, p_dev->temp_buffer,
365 | VL53L8CX_OFFSET_BUFFER_SIZE);
366 | status |= _vl53l8cx_send_offset_data(p_dev, VL53L8CX_RESOLUTION_4X4);
367 |
368 | /* Set default Xtalk shape. Send Xtalk to sensor */
369 | (void)memcpy(p_dev->xtalk_data, (uint8_t *)VL53L8CX_DEFAULT_XTALK,
370 | VL53L8CX_XTALK_BUFFER_SIZE);
371 | status |= _vl53l8cx_send_xtalk_data(p_dev, VL53L8CX_RESOLUTION_4X4);
372 |
373 | /* Send default configuration to VL53L8CX firmware */
374 | status |= VL53L8CX_WrMulti(&(p_dev->platform), 0x2c34,
375 | p_dev->default_configuration,
376 | sizeof(VL53L8CX_DEFAULT_CONFIGURATION));
377 | status |= _vl53l8cx_poll_for_answer(p_dev, 4, 1,
378 | VL53L8CX_UI_CMD_STATUS, 0xff, 0x03);
379 |
380 | status |= vl53l8cx_dci_write_data(p_dev, (uint8_t *)&pipe_ctrl,
381 | VL53L8CX_DCI_PIPE_CONTROL, (uint16_t)sizeof(pipe_ctrl));
382 | #if VL53L8CX_NB_TARGET_PER_ZONE != 1
383 | tmp = VL53L8CX_NB_TARGET_PER_ZONE;
384 | status |= vl53l8cx_dci_replace_data(p_dev, p_dev->temp_buffer,
385 | VL53L8CX_DCI_FW_NB_TARGET, 16,
386 | (uint8_t *)&tmp, 1, 0x0C);
387 | #endif
388 |
389 | status |= vl53l8cx_dci_write_data(p_dev, (uint8_t *)&single_range,
390 | VL53L8CX_DCI_SINGLE_RANGE,
391 | (uint16_t)sizeof(single_range));
392 |
393 | exit:
394 | return status;
395 | }
396 |
397 | uint8_t vl53l8cx_set_i2c_address(
398 | VL53L8CX_Configuration *p_dev,
399 | uint16_t i2c_address)
400 | {
401 | uint8_t status = VL53L8CX_STATUS_OK;
402 |
403 | status |= VL53L8CX_WrByte(&(p_dev->platform), 0x7fff, 0x00);
404 | status |= VL53L8CX_WrByte(&(p_dev->platform), 0x4, (uint8_t)(i2c_address >> 1));
405 | p_dev->platform.address = i2c_address;
406 | status |= VL53L8CX_WrByte(&(p_dev->platform), 0x7fff, 0x02);
407 |
408 | return status;
409 | }
410 |
411 | uint8_t vl53l8cx_get_power_mode(
412 | VL53L8CX_Configuration *p_dev,
413 | uint8_t *p_power_mode)
414 | {
415 | uint8_t tmp, status = VL53L8CX_STATUS_OK;
416 |
417 | status |= VL53L8CX_WrByte(&(p_dev->platform), 0x7FFF, 0x00);
418 | status |= VL53L8CX_RdByte(&(p_dev->platform), 0x009, &tmp);
419 |
420 | switch (tmp) {
421 | case 0x4:
422 | *p_power_mode = VL53L8CX_POWER_MODE_WAKEUP;
423 | break;
424 | case 0x2:
425 | status |= VL53L8CX_RdByte(&(p_dev->platform), 0x000F, &tmp);
426 | if (tmp == 0x43) {
427 | *p_power_mode = VL53L8CX_POWER_MODE_DEEP_SLEEP;
428 | } else {
429 | *p_power_mode = VL53L8CX_POWER_MODE_SLEEP;
430 | }
431 |
432 | break;
433 | default:
434 | *p_power_mode = 0;
435 | status = VL53L8CX_STATUS_ERROR;
436 | break;
437 | }
438 |
439 | status |= VL53L8CX_WrByte(&(p_dev->platform), 0x7FFF, 0x02);
440 |
441 | return status;
442 | }
443 |
444 | uint8_t vl53l8cx_set_power_mode(
445 | VL53L8CX_Configuration *p_dev,
446 | uint8_t power_mode)
447 | {
448 | uint8_t current_power_mode, stored_mode, status = VL53L8CX_STATUS_OK;
449 |
450 | status |= vl53l8cx_get_power_mode(p_dev, ¤t_power_mode);
451 | if (power_mode != current_power_mode) {
452 | switch (power_mode) {
453 | case VL53L8CX_POWER_MODE_WAKEUP:
454 | status |= VL53L8CX_WrByte(&(p_dev->platform), 0x7FFF, 0x00);
455 | status |= VL53L8CX_WrByte(&(p_dev->platform), 0x09, 0x04);
456 | status |= VL53L8CX_RdByte(&(p_dev->platform), 0x000F, &stored_mode);
457 | if (stored_mode == 0x43) { /* Only for deep sleep mode */
458 | status |= VL53L8CX_WrByte(&(p_dev->platform), 0x000F, 0x40);
459 | }
460 | status |= _vl53l8cx_poll_for_answer(
461 | p_dev, 1, 0, 0x06, 0x01, 1);
462 | if (stored_mode == 0x43) { /* Only for deep sleep mode */
463 | status |= vl53l8cx_init(p_dev);
464 | }
465 | break;
466 |
467 | case VL53L8CX_POWER_MODE_SLEEP:
468 | status |= VL53L8CX_WrByte(&(p_dev->platform), 0x7FFF, 0x00);
469 | status |= VL53L8CX_WrByte(&(p_dev->platform), 0x09, 0x02);
470 | status |= _vl53l8cx_poll_for_answer(
471 | p_dev, 1, 0, 0x06, 0x01, 0);
472 | break;
473 |
474 | case VL53L8CX_POWER_MODE_DEEP_SLEEP:
475 | status |= VL53L8CX_WrByte(&(p_dev->platform), 0x7FFF, 0x00);
476 | status |= VL53L8CX_WrByte(&(p_dev->platform), 0x09, 0x02);
477 | status |= _vl53l8cx_poll_for_answer(
478 | p_dev, 1, 0, 0x06, 0x01, 0);
479 | status |= VL53L8CX_WrByte(&(p_dev->platform), 0x000F, 0x43);
480 | break;
481 |
482 | default:
483 | status = VL53L8CX_STATUS_ERROR;
484 | break;
485 | }
486 | status |= VL53L8CX_WrByte(&(p_dev->platform), 0x7FFF, 0x02);
487 | }
488 |
489 | return status;
490 | }
491 |
492 | uint8_t vl53l8cx_start_ranging(
493 | VL53L8CX_Configuration *p_dev)
494 | {
495 | uint8_t resolution, status = VL53L8CX_STATUS_OK;
496 | uint16_t tmp;
497 | uint32_t i;
498 | uint32_t header_config[2] = {0, 0};
499 |
500 | union Block_header *bh_ptr;
501 | uint8_t cmd[] = {0x00, 0x03, 0x00, 0x00};
502 |
503 | status |= vl53l8cx_get_resolution(p_dev, &resolution);
504 | p_dev->data_read_size = 0;
505 | p_dev->streamcount = 255;
506 |
507 | /* Enable mandatory output (meta and common data) */
508 | uint32_t output_bh_enable[] = {
509 | 0x00000007U,
510 | 0x00000000U,
511 | 0x00000000U,
512 | 0xC0000000U
513 | };
514 |
515 | /* Send addresses of possible output */
516 | uint32_t output[] = {VL53L8CX_START_BH,
517 | VL53L8CX_METADATA_BH,
518 | VL53L8CX_COMMONDATA_BH,
519 | VL53L8CX_AMBIENT_RATE_BH,
520 | VL53L8CX_SPAD_COUNT_BH,
521 | VL53L8CX_NB_TARGET_DETECTED_BH,
522 | VL53L8CX_SIGNAL_RATE_BH,
523 | VL53L8CX_RANGE_SIGMA_MM_BH,
524 | VL53L8CX_DISTANCE_BH,
525 | VL53L8CX_REFLECTANCE_BH,
526 | VL53L8CX_TARGET_STATUS_BH,
527 | VL53L8CX_MOTION_DETECT_BH
528 | };
529 |
530 | /* Enable selected outputs in the 'platform.h' file */
531 | #ifndef VL53L8CX_DISABLE_AMBIENT_PER_SPAD
532 | output_bh_enable[0] += (uint32_t)8;
533 | #endif
534 | #ifndef VL53L8CX_DISABLE_NB_SPADS_ENABLED
535 | output_bh_enable[0] += (uint32_t)16;
536 | #endif
537 | #ifndef VL53L8CX_DISABLE_NB_TARGET_DETECTED
538 | output_bh_enable[0] += (uint32_t)32;
539 | #endif
540 | #ifndef VL53L8CX_DISABLE_SIGNAL_PER_SPAD
541 | output_bh_enable[0] += (uint32_t)64;
542 | #endif
543 | #ifndef VL53L8CX_DISABLE_RANGE_SIGMA_MM
544 | output_bh_enable[0] += (uint32_t)128;
545 | #endif
546 | #ifndef VL53L8CX_DISABLE_DISTANCE_MM
547 | output_bh_enable[0] += (uint32_t)256;
548 | #endif
549 | #ifndef VL53L8CX_DISABLE_REFLECTANCE_PERCENT
550 | output_bh_enable[0] += (uint32_t)512;
551 | #endif
552 | #ifndef VL53L8CX_DISABLE_TARGET_STATUS
553 | output_bh_enable[0] += (uint32_t)1024;
554 | #endif
555 | #ifndef VL53L8CX_DISABLE_MOTION_INDICATOR
556 | output_bh_enable[0] += (uint32_t)2048;
557 | #endif
558 |
559 | /* Update data size */
560 | for (i = 0; i < (uint32_t)(sizeof(output) / sizeof(uint32_t)); i++) {
561 | if ((output[i] == (uint8_t)0)
562 | || ((output_bh_enable[i / (uint32_t)32]
563 | & ((uint32_t)1 << (i % (uint32_t)32))) == (uint32_t)0)) {
564 | continue;
565 | }
566 |
567 | bh_ptr = (union Block_header *) & (output[i]);
568 | if (((uint8_t)bh_ptr->type >= (uint8_t)0x1)
569 | && ((uint8_t)bh_ptr->type < (uint8_t)0x0d)) {
570 | if ((bh_ptr->idx >= (uint16_t)0x54d0)
571 | && (bh_ptr->idx < (uint16_t)(0x54d0 + 960))) {
572 | bh_ptr->size = resolution;
573 | } else {
574 | bh_ptr->size = (uint16_t)((uint16_t)resolution
575 | * (uint16_t)VL53L8CX_NB_TARGET_PER_ZONE);
576 | }
577 | p_dev->data_read_size += bh_ptr->type * bh_ptr->size;
578 | } else {
579 | p_dev->data_read_size += bh_ptr->size;
580 | }
581 | p_dev->data_read_size += (uint32_t)4;
582 | }
583 | p_dev->data_read_size += (uint32_t)24;
584 |
585 | status |= vl53l8cx_dci_write_data(p_dev,
586 | (uint8_t *) & (output), VL53L8CX_DCI_OUTPUT_LIST,
587 | (uint16_t)sizeof(output));
588 |
589 | header_config[0] = p_dev->data_read_size;
590 | header_config[1] = i + (uint32_t)1;
591 |
592 | status |= vl53l8cx_dci_write_data(p_dev,
593 | (uint8_t *) & (header_config), VL53L8CX_DCI_OUTPUT_CONFIG,
594 | (uint16_t)sizeof(header_config));
595 |
596 | status |= vl53l8cx_dci_write_data(p_dev,
597 | (uint8_t *) & (output_bh_enable), VL53L8CX_DCI_OUTPUT_ENABLES,
598 | (uint16_t)sizeof(output_bh_enable));
599 |
600 | /* Start xshut bypass (interrupt mode) */
601 | status |= VL53L8CX_WrByte(&(p_dev->platform), 0x7fff, 0x00);
602 | status |= VL53L8CX_WrByte(&(p_dev->platform), 0x09, 0x05);
603 | status |= VL53L8CX_WrByte(&(p_dev->platform), 0x7fff, 0x02);
604 |
605 | /* Start ranging session */
606 | status |= VL53L8CX_WrMulti(&(p_dev->platform), VL53L8CX_UI_CMD_END -
607 | (uint16_t)(4 - 1), (uint8_t *)cmd, sizeof(cmd));
608 | status |= _vl53l8cx_poll_for_answer(p_dev, 4, 1,
609 | VL53L8CX_UI_CMD_STATUS, 0xff, 0x03);
610 |
611 | /* Read ui range data content and compare if data size is the correct one */
612 | status |= vl53l8cx_dci_read_data(p_dev,
613 | (uint8_t *)p_dev->temp_buffer, 0x5440, 12);
614 | (void)memcpy(&tmp, &(p_dev->temp_buffer[0x8]), sizeof(tmp));
615 | if (tmp != p_dev->data_read_size) {
616 | status |= VL53L8CX_STATUS_ERROR;
617 | }
618 |
619 | /* Ensure that there is no laser safety fault */
620 | status |= vl53l8cx_dci_read_data(p_dev,
621 | (uint8_t *)p_dev->temp_buffer, 0xE0C4, 8);
622 | if ((uint8_t)p_dev->temp_buffer[0x6] != (uint8_t)0) {
623 | status |= VL53L8CX_STATUS_LASER_SAFETY;
624 | }
625 |
626 | return status;
627 | }
628 |
629 | uint8_t vl53l8cx_stop_ranging(
630 | VL53L8CX_Configuration *p_dev)
631 | {
632 | uint8_t tmp = 0, status = VL53L8CX_STATUS_OK;
633 | uint16_t timeout = 0;
634 | uint32_t auto_stop_flag = 0;
635 |
636 | status |= VL53L8CX_RdMulti(&(p_dev->platform),
637 | 0x2FFC, (uint8_t *)&auto_stop_flag, 4);
638 | if ((auto_stop_flag != (uint32_t)0x4FF)
639 | && (p_dev->is_auto_stop_enabled == (uint8_t)0)) {
640 | status |= VL53L8CX_WrByte(&(p_dev->platform), 0x7fff, 0x00);
641 |
642 | /* Provoke MCU stop */
643 | status |= VL53L8CX_WrByte(&(p_dev->platform), 0x15, 0x16);
644 | status |= VL53L8CX_WrByte(&(p_dev->platform), 0x14, 0x01);
645 |
646 | /* Poll for G02 status 0 MCU stop */
647 | while (((tmp & (uint8_t)0x80) >> 7) == (uint8_t)0x00) {
648 | status |= VL53L8CX_RdByte(&(p_dev->platform), 0x6, &tmp);
649 | status |= VL53L8CX_WaitMs(&(p_dev->platform), 10);
650 | timeout++; /* Timeout reached after 5 seconds */
651 |
652 | if (timeout > (uint16_t)500) {
653 | status |= tmp;
654 | break;
655 | }
656 | }
657 | }
658 |
659 | /* Check GO2 status 1 if status is still OK */
660 | status |= VL53L8CX_RdByte(&(p_dev->platform), 0x6, &tmp);
661 | if ((tmp & (uint8_t)0x80) != (uint8_t)0) {
662 | status |= VL53L8CX_RdByte(&(p_dev->platform), 0x7, &tmp);
663 | if ((tmp != (uint8_t)0x84) && (tmp != (uint8_t)0x85)) {
664 | status |= tmp;
665 | }
666 | }
667 |
668 | /* Undo MCU stop */
669 | status |= VL53L8CX_WrByte(&(p_dev->platform), 0x7fff, 0x00);
670 | status |= VL53L8CX_WrByte(&(p_dev->platform), 0x14, 0x00);
671 | status |= VL53L8CX_WrByte(&(p_dev->platform), 0x15, 0x00);
672 |
673 | /* Stop xshut bypass */
674 | status |= VL53L8CX_WrByte(&(p_dev->platform), 0x09, 0x04);
675 | status |= VL53L8CX_WrByte(&(p_dev->platform), 0x7fff, 0x02);
676 |
677 | return status;
678 | }
679 |
680 | uint8_t vl53l8cx_check_data_ready(
681 | VL53L8CX_Configuration *p_dev,
682 | uint8_t *p_isReady)
683 | {
684 | uint8_t status = VL53L8CX_STATUS_OK;
685 |
686 | status |= VL53L8CX_RdMulti(&(p_dev->platform), 0x0, p_dev->temp_buffer, 4);
687 |
688 | if ((p_dev->temp_buffer[0] != p_dev->streamcount)
689 | && (p_dev->temp_buffer[0] != (uint8_t)255)
690 | && (p_dev->temp_buffer[1] == (uint8_t)0x5)
691 | && ((p_dev->temp_buffer[2] & (uint8_t)0x5) == (uint8_t)0x5)
692 | && ((p_dev->temp_buffer[3] & (uint8_t)0x10) == (uint8_t)0x10)
693 | ) {
694 | *p_isReady = (uint8_t)1;
695 | p_dev->streamcount = p_dev->temp_buffer[0];
696 | } else {
697 | if ((p_dev->temp_buffer[3] & (uint8_t)0x80) != (uint8_t)0) {
698 | status |= p_dev->temp_buffer[2]; /* Return GO2 error status */
699 | }
700 |
701 | *p_isReady = 0;
702 | }
703 |
704 | return status;
705 | }
706 |
707 | uint8_t vl53l8cx_get_ranging_data(
708 | VL53L8CX_Configuration *p_dev,
709 | VL53L8CX_ResultsData *p_results)
710 | {
711 | uint8_t status = VL53L8CX_STATUS_OK;
712 | uint16_t header_id, footer_id;
713 | union Block_header *bh_ptr;
714 | uint32_t i, j, msize;
715 | status |= VL53L8CX_RdMulti(&(p_dev->platform), 0x0,
716 | p_dev->temp_buffer, p_dev->data_read_size);
717 | p_dev->streamcount = p_dev->temp_buffer[0];
718 | VL53L8CX_SwapBuffer(p_dev->temp_buffer, (uint16_t)p_dev->data_read_size);
719 |
720 | /* Start conversion at position 16 to avoid headers */
721 | for (i = (uint32_t)16; i
722 | < (uint32_t)p_dev->data_read_size; i += (uint32_t)4) {
723 | bh_ptr = (union Block_header *) & (p_dev->temp_buffer[i]);
724 | if ((bh_ptr->type > (uint32_t)0x1)
725 | && (bh_ptr->type < (uint32_t)0xd)) {
726 | msize = bh_ptr->type * bh_ptr->size;
727 | } else {
728 | msize = bh_ptr->size;
729 | }
730 |
731 | switch (bh_ptr->idx) {
732 | case VL53L8CX_METADATA_IDX:
733 | p_results->silicon_temp_degc =
734 | (int8_t)p_dev->temp_buffer[i + (uint32_t)12];
735 | break;
736 |
737 | #ifndef VL53L8CX_DISABLE_AMBIENT_PER_SPAD
738 | case VL53L8CX_AMBIENT_RATE_IDX:
739 | (void)memcpy(p_results->ambient_per_spad,
740 | &(p_dev->temp_buffer[i + (uint32_t)4]), msize);
741 | break;
742 | #endif
743 | #ifndef VL53L8CX_DISABLE_NB_SPADS_ENABLED
744 | case VL53L8CX_SPAD_COUNT_IDX:
745 | (void)memcpy(p_results->nb_spads_enabled,
746 | &(p_dev->temp_buffer[i + (uint32_t)4]), msize);
747 | break;
748 | #endif
749 | #ifndef VL53L8CX_DISABLE_NB_TARGET_DETECTED
750 | case VL53L8CX_NB_TARGET_DETECTED_IDX:
751 | (void)memcpy(p_results->nb_target_detected,
752 | &(p_dev->temp_buffer[i + (uint32_t)4]), msize);
753 | break;
754 | #endif
755 | #ifndef VL53L8CX_DISABLE_SIGNAL_PER_SPAD
756 | case VL53L8CX_SIGNAL_RATE_IDX:
757 | (void)memcpy(p_results->signal_per_spad,
758 | &(p_dev->temp_buffer[i + (uint32_t)4]), msize);
759 | break;
760 | #endif
761 | #ifndef VL53L8CX_DISABLE_RANGE_SIGMA_MM
762 | case VL53L8CX_RANGE_SIGMA_MM_IDX:
763 | (void)memcpy(p_results->range_sigma_mm,
764 | &(p_dev->temp_buffer[i + (uint32_t)4]), msize);
765 | break;
766 | #endif
767 | #ifndef VL53L8CX_DISABLE_DISTANCE_MM
768 | case VL53L8CX_DISTANCE_IDX:
769 | (void)memcpy(p_results->distance_mm,
770 | &(p_dev->temp_buffer[i + (uint32_t)4]), msize);
771 | break;
772 | #endif
773 | #ifndef VL53L8CX_DISABLE_REFLECTANCE_PERCENT
774 | case VL53L8CX_REFLECTANCE_EST_PC_IDX:
775 | (void)memcpy(p_results->reflectance,
776 | &(p_dev->temp_buffer[i + (uint32_t)4]), msize);
777 | break;
778 | #endif
779 | #ifndef VL53L8CX_DISABLE_TARGET_STATUS
780 | case VL53L8CX_TARGET_STATUS_IDX:
781 | (void)memcpy(p_results->target_status,
782 | &(p_dev->temp_buffer[i + (uint32_t)4]), msize);
783 | break;
784 | #endif
785 | #ifndef VL53L8CX_DISABLE_MOTION_INDICATOR
786 | case VL53L8CX_MOTION_DETEC_IDX:
787 | (void)memcpy(&p_results->motion_indicator,
788 | &(p_dev->temp_buffer[i + (uint32_t)4]), msize);
789 | break;
790 | #endif
791 | default:
792 | break;
793 | }
794 | i += msize;
795 | }
796 |
797 | #ifndef VL53L8CX_USE_RAW_FORMAT
798 |
799 | /* Convert data into their real format */
800 | #ifndef VL53L8CX_DISABLE_AMBIENT_PER_SPAD
801 | for (i = 0; i < (uint32_t)VL53L8CX_RESOLUTION_8X8; i++) {
802 | p_results->ambient_per_spad[i] /= (uint32_t)2048;
803 | }
804 | #endif
805 |
806 | for (i = 0; i < (uint32_t)(VL53L8CX_RESOLUTION_8X8
807 | *VL53L8CX_NB_TARGET_PER_ZONE); i++) {
808 | #ifndef VL53L8CX_DISABLE_DISTANCE_MM
809 | p_results->distance_mm[i] /= 4;
810 | #endif
811 | #ifndef VL53L8CX_DISABLE_REFLECTANCE_PERCENT
812 | p_results->reflectance[i] /= (uint8_t)2;
813 | #endif
814 | #ifndef VL53L8CX_DISABLE_RANGE_SIGMA_MM
815 | p_results->range_sigma_mm[i] /= (uint16_t)128;
816 | #endif
817 | #ifndef VL53L8CX_DISABLE_SIGNAL_PER_SPAD
818 | p_results->signal_per_spad[i] /= (uint32_t)2048;
819 | #endif
820 | }
821 |
822 | /* Set target status to 255 if no target is detected for this zone */
823 | #ifndef VL53L8CX_DISABLE_NB_TARGET_DETECTED
824 | for (i = 0; i < (uint32_t)VL53L8CX_RESOLUTION_8X8; i++) {
825 | if (p_results->nb_target_detected[i] == (uint8_t)0) {
826 | for (j = 0; j < (uint32_t)
827 | VL53L8CX_NB_TARGET_PER_ZONE; j++) {
828 | #ifndef VL53L8CX_DISABLE_TARGET_STATUS
829 | p_results->target_status
830 | [((uint32_t)VL53L8CX_NB_TARGET_PER_ZONE
831 | * (uint32_t)i) + j] = (uint8_t)255;
832 | #endif
833 | }
834 | }
835 | }
836 | #endif
837 |
838 | #ifndef VL53L8CX_DISABLE_MOTION_INDICATOR
839 | for (i = 0; i < (uint32_t)32; i++) {
840 | p_results->motion_indicator.motion[i] /= (uint32_t)65535;
841 | }
842 | #endif
843 |
844 | #endif
845 |
846 | /* Check if footer id and header id are matching. This allows to detect
847 | * corrupted frames */
848 | header_id = ((uint16_t)(p_dev->temp_buffer[0x8]) << 8) & 0xFF00U;
849 | header_id |= ((uint16_t)(p_dev->temp_buffer[0x9])) & 0x00FFU;
850 |
851 | footer_id = ((uint16_t)(p_dev->temp_buffer[p_dev->data_read_size
852 | - (uint32_t)4]) << 8) & 0xFF00U;
853 | footer_id |= ((uint16_t)(p_dev->temp_buffer[p_dev->data_read_size
854 | - (uint32_t)3])) & 0xFFU;
855 |
856 | if (header_id != footer_id) {
857 | status |= VL53L8CX_STATUS_CORRUPTED_FRAME;
858 | }
859 |
860 | return status;
861 | }
862 |
863 | uint8_t vl53l8cx_get_resolution(
864 | VL53L8CX_Configuration *p_dev,
865 | uint8_t *p_resolution)
866 | {
867 | uint8_t status = VL53L8CX_STATUS_OK;
868 |
869 | status |= vl53l8cx_dci_read_data(p_dev, p_dev->temp_buffer,
870 | VL53L8CX_DCI_ZONE_CONFIG, 8);
871 | *p_resolution = p_dev->temp_buffer[0x00] * p_dev->temp_buffer[0x01];
872 |
873 | return status;
874 | }
875 |
876 |
877 |
878 | uint8_t vl53l8cx_set_resolution(
879 | VL53L8CX_Configuration *p_dev,
880 | uint8_t resolution)
881 | {
882 | uint8_t status = VL53L8CX_STATUS_OK;
883 |
884 | switch (resolution) {
885 | case VL53L8CX_RESOLUTION_4X4:
886 | status |= vl53l8cx_dci_read_data(p_dev,
887 | p_dev->temp_buffer,
888 | VL53L8CX_DCI_DSS_CONFIG, 16);
889 | p_dev->temp_buffer[0x04] = 64;
890 | p_dev->temp_buffer[0x06] = 64;
891 | p_dev->temp_buffer[0x09] = 4;
892 | status |= vl53l8cx_dci_write_data(p_dev,
893 | p_dev->temp_buffer,
894 | VL53L8CX_DCI_DSS_CONFIG, 16);
895 |
896 | status |= vl53l8cx_dci_read_data(p_dev,
897 | p_dev->temp_buffer,
898 | VL53L8CX_DCI_ZONE_CONFIG, 8);
899 | p_dev->temp_buffer[0x00] = 4;
900 | p_dev->temp_buffer[0x01] = 4;
901 | p_dev->temp_buffer[0x04] = 8;
902 | p_dev->temp_buffer[0x05] = 8;
903 | status |= vl53l8cx_dci_write_data(p_dev,
904 | p_dev->temp_buffer,
905 | VL53L8CX_DCI_ZONE_CONFIG, 8);
906 | break;
907 |
908 | case VL53L8CX_RESOLUTION_8X8:
909 | status |= vl53l8cx_dci_read_data(p_dev,
910 | p_dev->temp_buffer,
911 | VL53L8CX_DCI_DSS_CONFIG, 16);
912 | p_dev->temp_buffer[0x04] = 16;
913 | p_dev->temp_buffer[0x06] = 16;
914 | p_dev->temp_buffer[0x09] = 1;
915 | status |= vl53l8cx_dci_write_data(p_dev,
916 | p_dev->temp_buffer,
917 | VL53L8CX_DCI_DSS_CONFIG, 16);
918 |
919 | status |= vl53l8cx_dci_read_data(p_dev,
920 | p_dev->temp_buffer,
921 | VL53L8CX_DCI_ZONE_CONFIG, 8);
922 | p_dev->temp_buffer[0x00] = 8;
923 | p_dev->temp_buffer[0x01] = 8;
924 | p_dev->temp_buffer[0x04] = 4;
925 | p_dev->temp_buffer[0x05] = 4;
926 | status |= vl53l8cx_dci_write_data(p_dev,
927 | p_dev->temp_buffer,
928 | VL53L8CX_DCI_ZONE_CONFIG, 8);
929 |
930 | break;
931 |
932 | default:
933 | status = VL53L8CX_STATUS_INVALID_PARAM;
934 | break;
935 | }
936 |
937 | status |= _vl53l8cx_send_offset_data(p_dev, resolution);
938 | status |= _vl53l8cx_send_xtalk_data(p_dev, resolution);
939 |
940 | return status;
941 | }
942 |
943 | uint8_t vl53l8cx_get_ranging_frequency_hz(
944 | VL53L8CX_Configuration *p_dev,
945 | uint8_t *p_frequency_hz)
946 | {
947 | uint8_t status = VL53L8CX_STATUS_OK;
948 |
949 | status |= vl53l8cx_dci_read_data(p_dev, (uint8_t *)p_dev->temp_buffer,
950 | VL53L8CX_DCI_FREQ_HZ, 4);
951 | *p_frequency_hz = p_dev->temp_buffer[0x01];
952 |
953 | return status;
954 | }
955 |
956 | uint8_t vl53l8cx_set_ranging_frequency_hz(
957 | VL53L8CX_Configuration *p_dev,
958 | uint8_t frequency_hz)
959 | {
960 | uint8_t status = VL53L8CX_STATUS_OK;
961 |
962 | status |= vl53l8cx_dci_replace_data(p_dev, p_dev->temp_buffer,
963 | VL53L8CX_DCI_FREQ_HZ, 4,
964 | (uint8_t *)&frequency_hz, 1, 0x01);
965 |
966 | return status;
967 | }
968 |
969 | uint8_t vl53l8cx_get_integration_time_ms(
970 | VL53L8CX_Configuration *p_dev,
971 | uint32_t *p_time_ms)
972 | {
973 | uint8_t status = VL53L8CX_STATUS_OK;
974 |
975 | status |= vl53l8cx_dci_read_data(p_dev, (uint8_t *)p_dev->temp_buffer,
976 | VL53L8CX_DCI_INT_TIME, 20);
977 |
978 | (void)memcpy(p_time_ms, &(p_dev->temp_buffer[0x0]), 4);
979 | *p_time_ms /= (uint32_t)1000;
980 |
981 | return status;
982 | }
983 |
984 | uint8_t vl53l8cx_set_integration_time_ms(
985 | VL53L8CX_Configuration *p_dev,
986 | uint32_t integration_time_ms)
987 | {
988 | uint8_t status = VL53L8CX_STATUS_OK;
989 | uint32_t integration = integration_time_ms;
990 |
991 | /* Integration time must be between 2ms and 1000ms */
992 | if ((integration < (uint32_t)2)
993 | || (integration > (uint32_t)1000)) {
994 | status |= VL53L8CX_STATUS_INVALID_PARAM;
995 | } else {
996 | integration *= (uint32_t)1000;
997 |
998 | status |= vl53l8cx_dci_replace_data(p_dev, p_dev->temp_buffer,
999 | VL53L8CX_DCI_INT_TIME, 20,
1000 | (uint8_t *)&integration, 4, 0x00);
1001 | }
1002 |
1003 | return status;
1004 | }
1005 |
1006 | uint8_t vl53l8cx_get_sharpener_percent(
1007 | VL53L8CX_Configuration *p_dev,
1008 | uint8_t *p_sharpener_percent)
1009 | {
1010 | uint8_t status = VL53L8CX_STATUS_OK;
1011 |
1012 | status |= vl53l8cx_dci_read_data(p_dev, p_dev->temp_buffer,
1013 | VL53L8CX_DCI_SHARPENER, 16);
1014 |
1015 | *p_sharpener_percent = (p_dev->temp_buffer[0xD]
1016 | * (uint8_t)100) / (uint8_t)255;
1017 |
1018 | return status;
1019 | }
1020 |
1021 | uint8_t vl53l8cx_set_sharpener_percent(
1022 | VL53L8CX_Configuration *p_dev,
1023 | uint8_t sharpener_percent)
1024 | {
1025 | uint8_t status = VL53L8CX_STATUS_OK;
1026 | uint8_t sharpener;
1027 |
1028 | if (sharpener_percent >= (uint8_t)100) {
1029 | status |= VL53L8CX_STATUS_INVALID_PARAM;
1030 | } else {
1031 | sharpener = (sharpener_percent * (uint8_t)255) / (uint8_t)100;
1032 | status |= vl53l8cx_dci_replace_data(p_dev, p_dev->temp_buffer,
1033 | VL53L8CX_DCI_SHARPENER, 16,
1034 | (uint8_t *)&sharpener, 1, 0xD);
1035 | }
1036 |
1037 | return status;
1038 | }
1039 |
1040 | uint8_t vl53l8cx_get_target_order(
1041 | VL53L8CX_Configuration *p_dev,
1042 | uint8_t *p_target_order)
1043 | {
1044 | uint8_t status = VL53L8CX_STATUS_OK;
1045 |
1046 | status |= vl53l8cx_dci_read_data(p_dev, (uint8_t *)p_dev->temp_buffer,
1047 | VL53L8CX_DCI_TARGET_ORDER, 4);
1048 | *p_target_order = (uint8_t)p_dev->temp_buffer[0x0];
1049 |
1050 | return status;
1051 | }
1052 |
1053 | uint8_t vl53l8cx_set_target_order(
1054 | VL53L8CX_Configuration *p_dev,
1055 | uint8_t target_order)
1056 | {
1057 | uint8_t status = VL53L8CX_STATUS_OK;
1058 |
1059 | if ((target_order == (uint8_t)VL53L8CX_TARGET_ORDER_CLOSEST)
1060 | || (target_order == (uint8_t)VL53L8CX_TARGET_ORDER_STRONGEST)) {
1061 | status |= vl53l8cx_dci_replace_data(p_dev, p_dev->temp_buffer,
1062 | VL53L8CX_DCI_TARGET_ORDER, 4,
1063 | (uint8_t *)&target_order, 1, 0x0);
1064 | } else {
1065 | status |= VL53L8CX_STATUS_INVALID_PARAM;
1066 | }
1067 |
1068 | return status;
1069 | }
1070 |
1071 | uint8_t vl53l8cx_get_ranging_mode(
1072 | VL53L8CX_Configuration *p_dev,
1073 | uint8_t *p_ranging_mode)
1074 | {
1075 | uint8_t status = VL53L8CX_STATUS_OK;
1076 |
1077 | status |= vl53l8cx_dci_read_data(p_dev, p_dev->temp_buffer,
1078 | VL53L8CX_DCI_RANGING_MODE, 8);
1079 |
1080 | if (p_dev->temp_buffer[0x01] == (uint8_t)0x1) {
1081 | *p_ranging_mode = VL53L8CX_RANGING_MODE_CONTINUOUS;
1082 | } else {
1083 | *p_ranging_mode = VL53L8CX_RANGING_MODE_AUTONOMOUS;
1084 | }
1085 |
1086 | return status;
1087 | }
1088 |
1089 | uint8_t vl53l8cx_set_ranging_mode(
1090 | VL53L8CX_Configuration *p_dev,
1091 | uint8_t ranging_mode)
1092 | {
1093 | uint8_t status = VL53L8CX_STATUS_OK;
1094 | uint32_t single_range = 0x00;
1095 |
1096 | status |= vl53l8cx_dci_read_data(p_dev, p_dev->temp_buffer,
1097 | VL53L8CX_DCI_RANGING_MODE, 8);
1098 |
1099 | switch (ranging_mode) {
1100 | case VL53L8CX_RANGING_MODE_CONTINUOUS:
1101 | p_dev->temp_buffer[0x01] = 0x1;
1102 | p_dev->temp_buffer[0x03] = 0x3;
1103 | single_range = 0x00;
1104 | break;
1105 |
1106 | case VL53L8CX_RANGING_MODE_AUTONOMOUS:
1107 | p_dev->temp_buffer[0x01] = 0x3;
1108 | p_dev->temp_buffer[0x03] = 0x2;
1109 | single_range = 0x01;
1110 | break;
1111 |
1112 | default:
1113 | status = VL53L8CX_STATUS_INVALID_PARAM;
1114 | break;
1115 | }
1116 |
1117 | status |= vl53l8cx_dci_write_data(p_dev, p_dev->temp_buffer,
1118 | VL53L8CX_DCI_RANGING_MODE, (uint16_t)8);
1119 |
1120 | status |= vl53l8cx_dci_write_data(p_dev, (uint8_t *)&single_range,
1121 | VL53L8CX_DCI_SINGLE_RANGE,
1122 | (uint16_t)sizeof(single_range));
1123 |
1124 | return status;
1125 | }
1126 |
1127 | uint8_t vl53l8cx_get_external_sync_pin_enable(
1128 | VL53L8CX_Configuration *p_dev,
1129 | uint8_t *p_is_sync_pin_enabled)
1130 | {
1131 | uint8_t status = VL53L8CX_STATUS_OK;
1132 |
1133 | status |= vl53l8cx_dci_read_data(p_dev, p_dev->temp_buffer,
1134 | VL53L8CX_DCI_SYNC_PIN, 4);
1135 |
1136 | /* Check bit 1 value (get sync pause bit) */
1137 | if ((p_dev->temp_buffer[3] & (uint8_t)0x2) != (uint8_t)0) {
1138 | *p_is_sync_pin_enabled = (uint8_t)1;
1139 | } else {
1140 | *p_is_sync_pin_enabled = (uint8_t)0;
1141 | }
1142 |
1143 | return status;
1144 | }
1145 |
1146 | uint8_t vl53l8cx_set_external_sync_pin_enable(
1147 | VL53L8CX_Configuration *p_dev,
1148 | uint8_t enable_sync_pin)
1149 | {
1150 | uint8_t status = VL53L8CX_STATUS_OK;
1151 | uint32_t tmp;
1152 |
1153 | status |= vl53l8cx_dci_read_data(p_dev, p_dev->temp_buffer,
1154 | VL53L8CX_DCI_SYNC_PIN, 4);
1155 | tmp = (uint32_t)p_dev->temp_buffer[3];
1156 |
1157 | /* Update bit 1 with mask (set sync pause bit) */
1158 | if (enable_sync_pin == (uint8_t)0) {
1159 | tmp &= ~(1UL << 1);
1160 |
1161 | } else {
1162 | tmp |= 1UL << 1;
1163 | }
1164 |
1165 | p_dev->temp_buffer[3] = (uint8_t)tmp;
1166 | status |= vl53l8cx_dci_write_data(p_dev, p_dev->temp_buffer,
1167 | VL53L8CX_DCI_SYNC_PIN, 4);
1168 |
1169 | return status;
1170 | }
1171 |
1172 | uint8_t vl53l8cx_get_VHV_repeat_count(
1173 | VL53L8CX_Configuration *p_dev,
1174 | uint32_t *p_repeat_count)
1175 | {
1176 | uint8_t status = VL53L8CX_STATUS_OK;
1177 | status |= vl53l8cx_dci_read_data(p_dev, (uint8_t *)p_dev->temp_buffer,
1178 | VL53L8CX_DCI_VHV_CONFIG, 16);
1179 |
1180 | *p_repeat_count = ((uint32_t)p_dev->temp_buffer[7] << 24)
1181 | | ((uint32_t)p_dev->temp_buffer[6] << 16)
1182 | | ((uint32_t)p_dev->temp_buffer[5] << 8)
1183 | | (uint32_t)p_dev->temp_buffer[4];
1184 |
1185 | return status;
1186 | }
1187 |
1188 | uint8_t vl53l8cx_set_VHV_repeat_count(
1189 | VL53L8CX_Configuration *p_dev,
1190 | uint32_t repeat_count)
1191 | {
1192 | uint8_t status = VL53L8CX_STATUS_OK;
1193 | status |= vl53l8cx_dci_replace_data(p_dev, p_dev->temp_buffer,
1194 | VL53L8CX_DCI_VHV_CONFIG, 16, (uint8_t *)&repeat_count, 4, 0x4);
1195 | return status;
1196 | }
1197 |
1198 | uint8_t vl53l8cx_dci_read_data(
1199 | VL53L8CX_Configuration *p_dev,
1200 | uint8_t *data,
1201 | uint32_t index,
1202 | uint16_t data_size)
1203 | {
1204 | int16_t i;
1205 | uint8_t status = VL53L8CX_STATUS_OK;
1206 | uint32_t rd_size = (uint32_t) data_size + (uint32_t)12;
1207 | uint8_t cmd[] = {0x00, 0x00, 0x00, 0x00,
1208 | 0x00, 0x00, 0x00, 0x0f,
1209 | 0x00, 0x02, 0x00, 0x08
1210 | };
1211 |
1212 | /* Check if tmp buffer is large enough */
1213 | if ((data_size + (uint16_t)12) > (uint16_t)VL53L8CX_TEMPORARY_BUFFER_SIZE) {
1214 | status |= VL53L8CX_STATUS_ERROR;
1215 | } else {
1216 | cmd[0] = (uint8_t)(index >> 8);
1217 | cmd[1] = (uint8_t)(index & (uint32_t)0xff);
1218 | cmd[2] = (uint8_t)((data_size & (uint16_t)0xff0) >> 4);
1219 | cmd[3] = (uint8_t)((data_size & (uint16_t)0xf) << 4);
1220 |
1221 | /* Request data reading from FW */
1222 | status |= VL53L8CX_WrMulti(&(p_dev->platform),
1223 | (VL53L8CX_UI_CMD_END - (uint16_t)11), cmd, sizeof(cmd));
1224 | status |= _vl53l8cx_poll_for_answer(p_dev, 4, 1,
1225 | VL53L8CX_UI_CMD_STATUS,
1226 | 0xff, 0x03);
1227 |
1228 | /* Read new data sent (4 bytes header + data_size + 8 bytes footer) */
1229 | status |= VL53L8CX_RdMulti(&(p_dev->platform), VL53L8CX_UI_CMD_START,
1230 | p_dev->temp_buffer, rd_size);
1231 | VL53L8CX_SwapBuffer(p_dev->temp_buffer, data_size + (uint16_t)12);
1232 |
1233 | /* Copy data from FW into input structure (-4 bytes to remove header) */
1234 | for (i = 0 ; i < (int16_t)data_size; i++) {
1235 | data[i] = p_dev->temp_buffer[i + 4];
1236 | }
1237 | }
1238 |
1239 | return status;
1240 | }
1241 |
1242 | uint8_t vl53l8cx_dci_write_data(
1243 | VL53L8CX_Configuration *p_dev,
1244 | uint8_t *data,
1245 | uint32_t index,
1246 | uint16_t data_size)
1247 | {
1248 | uint8_t status = VL53L8CX_STATUS_OK;
1249 | int16_t i;
1250 |
1251 | uint8_t headers[] = {0x00, 0x00, 0x00, 0x00};
1252 | uint8_t footer[] = {0x00, 0x00, 0x00, 0x0f, 0x05, 0x01,
1253 | (uint8_t)((data_size + (uint16_t)8) >> 8),
1254 | (uint8_t)((data_size + (uint16_t)8) & (uint8_t)0xFF)
1255 | };
1256 |
1257 | uint16_t address = (uint16_t)VL53L8CX_UI_CMD_END -
1258 | (data_size + (uint16_t)12) + (uint16_t)1;
1259 |
1260 | /* Check if cmd buffer is large enough */
1261 | if ((data_size + (uint16_t)12)
1262 | > (uint16_t)VL53L8CX_TEMPORARY_BUFFER_SIZE) {
1263 | status |= VL53L8CX_STATUS_ERROR;
1264 | } else {
1265 | headers[0] = (uint8_t)(index >> 8);
1266 | headers[1] = (uint8_t)(index & (uint32_t)0xff);
1267 | headers[2] = (uint8_t)(((data_size & (uint16_t)0xff0) >> 4));
1268 | headers[3] = (uint8_t)((data_size & (uint16_t)0xf) << 4);
1269 |
1270 | /* Copy data from structure to FW format (+4 bytes to add header) */
1271 | VL53L8CX_SwapBuffer(data, data_size);
1272 | for (i = (int16_t)data_size - (int16_t)1 ; i >= 0; i--) {
1273 | p_dev->temp_buffer[i + 4] = data[i];
1274 | }
1275 |
1276 | /* Add headers and footer */
1277 | (void)memcpy(&p_dev->temp_buffer[0], headers, sizeof(headers));
1278 | (void)memcpy(&p_dev->temp_buffer[data_size + (uint16_t)4],
1279 | footer, sizeof(footer));
1280 |
1281 | /* Send data to FW */
1282 | status |= VL53L8CX_WrMulti(&(p_dev->platform), address,
1283 | p_dev->temp_buffer,
1284 | (uint32_t)((uint32_t)data_size + (uint32_t)12));
1285 | status |= _vl53l8cx_poll_for_answer(p_dev, 4, 1,
1286 | VL53L8CX_UI_CMD_STATUS, 0xff, 0x03);
1287 |
1288 | VL53L8CX_SwapBuffer(data, data_size);
1289 | }
1290 |
1291 | return status;
1292 | }
1293 |
1294 | uint8_t vl53l8cx_dci_replace_data(
1295 | VL53L8CX_Configuration *p_dev,
1296 | uint8_t *data,
1297 | uint32_t index,
1298 | uint16_t data_size,
1299 | uint8_t *new_data,
1300 | uint16_t new_data_size,
1301 | uint16_t new_data_pos)
1302 | {
1303 | uint8_t status = VL53L8CX_STATUS_OK;
1304 |
1305 | status |= vl53l8cx_dci_read_data(p_dev, data, index, data_size);
1306 | (void)memcpy(&(data[new_data_pos]), new_data, new_data_size);
1307 | status |= vl53l8cx_dci_write_data(p_dev, data, index, data_size);
1308 |
1309 | return status;
1310 | }
1311 |
--------------------------------------------------------------------------------
/src/vl53l8cx_api.h:
--------------------------------------------------------------------------------
1 | /**
2 | *
3 | * Copyright (c) 2021 STMicroelectronics.
4 | * All rights reserved.
5 | *
6 | * This software is licensed under terms that can be found in the LICENSE file
7 | * in the root directory of this software component.
8 | * If no LICENSE file comes with this software, it is provided AS-IS.
9 | *
10 | ******************************************************************************
11 | */
12 |
13 | #ifndef VL53L8CX_API_H_
14 | #define VL53L8CX_API_H_
15 |
16 | #ifdef __cplusplus
17 | extern "C" {
18 | #endif
19 |
20 | #if defined (__ARMCC_VERSION) && (__ARMCC_VERSION < 6010050)
21 | #pragma anon_unions
22 | #endif
23 |
24 |
25 |
26 | #include "vl53l8cx_platform.h"
27 |
28 | /**
29 | * @brief Current driver version.
30 | */
31 |
32 | #define VL53L8CX_API_REVISION "VL53L8CX_1.3.0"
33 |
34 | /**
35 | * @brief Default I2C address of VL53L8CX sensor. Can be changed using function
36 | * vl53l8cx_set_i2c_address() function is called.
37 | */
38 |
39 | #define VL53L8CX_DEFAULT_I2C_ADDRESS ((uint16_t)0x52)
40 |
41 | /**
42 | * @brief Macro VL53L8CX_RESOLUTION_4X4 or VL53L8CX_RESOLUTION_8X8 allows
43 | * setting sensor in 4x4 mode or 8x8 mode, using function
44 | * vl53l8cx_set_resolution().
45 | */
46 |
47 | #define VL53L8CX_RESOLUTION_4X4 ((uint8_t) 16U)
48 | #define VL53L8CX_RESOLUTION_8X8 ((uint8_t) 64U)
49 |
50 |
51 | /**
52 | * @brief Macro VL53L8CX_TARGET_ORDER_STRONGEST or VL53L8CX_TARGET_ORDER_CLOSEST
53 | * are used to select the target order for data output.
54 | */
55 |
56 | #define VL53L8CX_TARGET_ORDER_CLOSEST ((uint8_t) 1U)
57 | #define VL53L8CX_TARGET_ORDER_STRONGEST ((uint8_t) 2U)
58 |
59 | /**
60 | * @brief Macro VL53L8CX_RANGING_MODE_CONTINUOUS and
61 | * VL53L8CX_RANGING_MODE_AUTONOMOUS are used to change the ranging mode.
62 | * Autonomous mode can be used to set a precise integration time, whereas
63 | * continuous is always maximum.
64 | */
65 |
66 | #define VL53L8CX_RANGING_MODE_CONTINUOUS ((uint8_t) 1U)
67 | #define VL53L8CX_RANGING_MODE_AUTONOMOUS ((uint8_t) 3U)
68 |
69 | /**
70 | * @brief The default power mode is VL53L8CX_POWER_MODE_WAKEUP. User can choose two
71 | * different modes to save power consumption when is the device
72 | * is not used:
73 | * - VL53L8CX_POWER_MODE_SLEEP: This mode retains the firmware and the configuration. It
74 | * is recommended when the device needs to quickly wake-up.
75 | * - VL53L8CX_POWER_MODE_DEEP_SLEEP: This mode clears all memory, by consequence the firmware,
76 | * the configuration and the calibration are lost. It is recommended when the device sleeps during
77 | * a long time as it consumes a very low current consumption.
78 | * Both modes can be changed using function vl53l8cx_set_power_mode().
79 | */
80 |
81 | #define VL53L8CX_POWER_MODE_SLEEP ((uint8_t) 0U)
82 | #define VL53L8CX_POWER_MODE_WAKEUP ((uint8_t) 1U)
83 | #define VL53L8CX_POWER_MODE_DEEP_SLEEP ((uint8_t) 2U)
84 |
85 | /**
86 | * @brief Macro VL53L8CX_STATUS_OK indicates that VL53L5 sensor has no error.
87 | * Macro VL53L8CX_STATUS_ERROR indicates that something is wrong (value,
88 | * I2C access, ...). Macro VL53L8CX_MCU_ERROR is used to indicate a MCU issue.
89 | */
90 |
91 | #define VL53L8CX_STATUS_OK ((uint8_t) 0U)
92 | #define VL53L8CX_STATUS_TIMEOUT_ERROR ((uint8_t) 1U)
93 | #define VL53L8CX_STATUS_CORRUPTED_FRAME ((uint8_t) 2U)
94 | #define VL53L8CX_STATUS_LASER_SAFETY ((uint8_t) 3U)
95 | #define VL53L8CX_STATUS_XTALK_FAILED ((uint8_t) 4U)
96 | #define VL53L8CX_STATUS_FW_CHECKSUM_FAIL ((uint8_t) 5U)
97 | #define VL53L8CX_MCU_ERROR ((uint8_t) 66U)
98 | #define VL53L8CX_STATUS_INVALID_PARAM ((uint8_t) 127U)
99 | #define VL53L8CX_STATUS_ERROR ((uint8_t) 255U)
100 |
101 | /**
102 | * @brief Definitions for Range results block headers
103 | */
104 |
105 | #if VL53L8CX_NB_TARGET_PER_ZONE == 1
106 |
107 | #define VL53L8CX_START_BH ((uint32_t)0x0000000DU)
108 | #define VL53L8CX_METADATA_BH ((uint32_t)0x54B400C0U)
109 | #define VL53L8CX_COMMONDATA_BH ((uint32_t)0x54C00040U)
110 | #define VL53L8CX_AMBIENT_RATE_BH ((uint32_t)0x54D00104U)
111 | #define VL53L8CX_SPAD_COUNT_BH ((uint32_t)0x55D00404U)
112 | #define VL53L8CX_NB_TARGET_DETECTED_BH ((uint32_t)0xDB840401U)
113 | #define VL53L8CX_SIGNAL_RATE_BH ((uint32_t)0xDBC40404U)
114 | #define VL53L8CX_RANGE_SIGMA_MM_BH ((uint32_t)0xDEC40402U)
115 | #define VL53L8CX_DISTANCE_BH ((uint32_t)0xDF440402U)
116 | #define VL53L8CX_REFLECTANCE_BH ((uint32_t)0xE0440401U)
117 | #define VL53L8CX_TARGET_STATUS_BH ((uint32_t)0xE0840401U)
118 | #define VL53L8CX_MOTION_DETECT_BH ((uint32_t)0xD85808C0U)
119 |
120 | #define VL53L8CX_METADATA_IDX ((uint16_t)0x54B4U)
121 | #define VL53L8CX_SPAD_COUNT_IDX ((uint16_t)0x55D0U)
122 | #define VL53L8CX_AMBIENT_RATE_IDX ((uint16_t)0x54D0U)
123 | #define VL53L8CX_NB_TARGET_DETECTED_IDX ((uint16_t)0xDB84U)
124 | #define VL53L8CX_SIGNAL_RATE_IDX ((uint16_t)0xDBC4U)
125 | #define VL53L8CX_RANGE_SIGMA_MM_IDX ((uint16_t)0xDEC4U)
126 | #define VL53L8CX_DISTANCE_IDX ((uint16_t)0xDF44U)
127 | #define VL53L8CX_REFLECTANCE_EST_PC_IDX ((uint16_t)0xE044U)
128 | #define VL53L8CX_TARGET_STATUS_IDX ((uint16_t)0xE084U)
129 | #define VL53L8CX_MOTION_DETEC_IDX ((uint16_t)0xD858U)
130 |
131 | #else
132 | #define VL53L8CX_START_BH ((uint32_t)0x0000000DU)
133 | #define VL53L8CX_METADATA_BH ((uint32_t)0x54B400C0U)
134 | #define VL53L8CX_COMMONDATA_BH ((uint32_t)0x54C00040U)
135 | #define VL53L8CX_AMBIENT_RATE_BH ((uint32_t)0x54D00104U)
136 | #define VL53L8CX_NB_TARGET_DETECTED_BH ((uint32_t)0x57D00401U)
137 | #define VL53L8CX_SPAD_COUNT_BH ((uint32_t)0x55D00404U)
138 | #define VL53L8CX_SIGNAL_RATE_BH ((uint32_t)0x58900404U)
139 | #define VL53L8CX_RANGE_SIGMA_MM_BH ((uint32_t)0x64900402U)
140 | #define VL53L8CX_DISTANCE_BH ((uint32_t)0x66900402U)
141 | #define VL53L8CX_REFLECTANCE_BH ((uint32_t)0x6A900401U)
142 | #define VL53L8CX_TARGET_STATUS_BH ((uint32_t)0x6B900401U)
143 | #define VL53L8CX_MOTION_DETECT_BH ((uint32_t)0xCC5008C0U)
144 |
145 | #define VL53L8CX_METADATA_IDX ((uint16_t)0x54B4U)
146 | #define VL53L8CX_SPAD_COUNT_IDX ((uint16_t)0x55D0U)
147 | #define VL53L8CX_AMBIENT_RATE_IDX ((uint16_t)0x54D0U)
148 | #define VL53L8CX_NB_TARGET_DETECTED_IDX ((uint16_t)0x57D0U)
149 | #define VL53L8CX_SIGNAL_RATE_IDX ((uint16_t)0x5890U)
150 | #define VL53L8CX_RANGE_SIGMA_MM_IDX ((uint16_t)0x6490U)
151 | #define VL53L8CX_DISTANCE_IDX ((uint16_t)0x6690U)
152 | #define VL53L8CX_REFLECTANCE_EST_PC_IDX ((uint16_t)0x6A90U)
153 | #define VL53L8CX_TARGET_STATUS_IDX ((uint16_t)0x6B90U)
154 | #define VL53L8CX_MOTION_DETEC_IDX ((uint16_t)0xCC50U)
155 | #endif
156 |
157 |
158 | /**
159 | * @brief Inner Macro for API. Not for user, only for development.
160 | */
161 |
162 | #define VL53L8CX_NVM_DATA_SIZE ((uint16_t)492U)
163 | #define VL53L8CX_CONFIGURATION_SIZE ((uint16_t)972U)
164 | #define VL53L8CX_OFFSET_BUFFER_SIZE ((uint16_t)488U)
165 | #define VL53L8CX_XTALK_BUFFER_SIZE ((uint16_t)776U)
166 |
167 | #define VL53L8CX_DCI_ZONE_CONFIG ((uint16_t)0x5450U)
168 | #define VL53L8CX_DCI_FREQ_HZ ((uint16_t)0x5458U)
169 | #define VL53L8CX_DCI_INT_TIME ((uint16_t)0x545CU)
170 | #define VL53L8CX_DCI_FW_NB_TARGET ((uint16_t)0x5478)
171 | #define VL53L8CX_DCI_RANGING_MODE ((uint16_t)0xAD30U)
172 | #define VL53L8CX_DCI_DSS_CONFIG ((uint16_t)0xAD38U)
173 | #define VL53L8CX_DCI_VHV_CONFIG ((uint16_t)0xAD60U)
174 | #define VL53L8CX_DCI_TARGET_ORDER ((uint16_t)0xAE64U)
175 | #define VL53L8CX_DCI_SHARPENER ((uint16_t)0xAED8U)
176 | #define VL53L8CX_DCI_INTERNAL_CP ((uint16_t)0xB39CU)
177 | #define VL53L8CX_DCI_SYNC_PIN ((uint16_t)0xB5F0U)
178 | #define VL53L8CX_DCI_MOTION_DETECTOR_CFG ((uint16_t)0xBFACU)
179 | #define VL53L8CX_DCI_SINGLE_RANGE ((uint16_t)0xD964U)
180 | #define VL53L8CX_DCI_OUTPUT_CONFIG ((uint16_t)0xD968U)
181 | #define VL53L8CX_DCI_OUTPUT_ENABLES ((uint16_t)0xD970U)
182 | #define VL53L8CX_DCI_OUTPUT_LIST ((uint16_t)0xD980U)
183 | #define VL53L8CX_DCI_PIPE_CONTROL ((uint16_t)0xDB80U)
184 |
185 | #define VL53L8CX_UI_CMD_STATUS ((uint16_t)0x2C00U)
186 | #define VL53L8CX_UI_CMD_START ((uint16_t)0x2C04U)
187 | #define VL53L8CX_UI_CMD_END ((uint16_t)0x2FFFU)
188 |
189 | /**
190 | * @brief Inner values for API. Max buffer size depends of the selected output.
191 | */
192 |
193 | #ifndef VL53L8CX_DISABLE_AMBIENT_PER_SPAD
194 | #define L5CX_AMB_SIZE 260U
195 | #else
196 | #define L5CX_AMB_SIZE 0U
197 | #endif
198 |
199 | #ifndef VL53L8CX_DISABLE_NB_SPADS_ENABLED
200 | #define L5CX_SPAD_SIZE 260U
201 | #else
202 | #define L5CX_SPAD_SIZE 0U
203 | #endif
204 |
205 | #ifndef VL53L8CX_DISABLE_NB_TARGET_DETECTED
206 | #define L5CX_NTAR_SIZE 68U
207 | #else
208 | #define L5CX_NTAR_SIZE 0U
209 | #endif
210 |
211 | #ifndef VL53L8CX_DISABLE_SIGNAL_PER_SPAD
212 | #define L5CX_SPS_SIZE ((256U * VL53L8CX_NB_TARGET_PER_ZONE) + 4U)
213 | #else
214 | #define L5CX_SPS_SIZE 0U
215 | #endif
216 |
217 | #ifndef VL53L8CX_DISABLE_RANGE_SIGMA_MM
218 | #define L5CX_SIGR_SIZE ((128U * VL53L8CX_NB_TARGET_PER_ZONE) + 4U)
219 | #else
220 | #define L5CX_SIGR_SIZE 0U
221 | #endif
222 |
223 | #ifndef VL53L8CX_DISABLE_DISTANCE_MM
224 | #define L5CX_DIST_SIZE ((128U * VL53L8CX_NB_TARGET_PER_ZONE) + 4U)
225 | #else
226 | #define L5CX_DIST_SIZE 0U
227 | #endif
228 |
229 | #ifndef VL53L8CX_DISABLE_REFLECTANCE_PERCENT
230 | #define L5CX_RFLEST_SIZE ((64U *VL53L8CX_NB_TARGET_PER_ZONE) + 4U)
231 | #else
232 | #define L5CX_RFLEST_SIZE 0U
233 | #endif
234 |
235 | #ifndef VL53L8CX_DISABLE_TARGET_STATUS
236 | #define L5CX_STA_SIZE ((64U *VL53L8CX_NB_TARGET_PER_ZONE) + 4U)
237 | #else
238 | #define L5CX_STA_SIZE 0U
239 | #endif
240 |
241 | #ifndef VL53L8CX_DISABLE_MOTION_INDICATOR
242 | #define L5CX_MOT_SIZE 144U
243 | #else
244 | #define L5CX_MOT_SIZE 0U
245 | #endif
246 |
247 | /**
248 | * @brief Macro VL53L8CX_MAX_RESULTS_SIZE indicates the maximum size used by
249 | * output through I2C. Value 40 corresponds to headers + meta-data + common-data
250 | * and 20 corresponds to the footer.
251 | */
252 |
253 | #define VL53L8CX_MAX_RESULTS_SIZE ( 40U \
254 | + L5CX_AMB_SIZE + L5CX_SPAD_SIZE + L5CX_NTAR_SIZE + L5CX_SPS_SIZE \
255 | + L5CX_SIGR_SIZE + L5CX_DIST_SIZE + L5CX_RFLEST_SIZE + L5CX_STA_SIZE \
256 | + L5CX_MOT_SIZE + 20U)
257 |
258 | /**
259 | * @brief Macro VL53L8CX_TEMPORARY_BUFFER_SIZE can be used to know the size of
260 | * the temporary buffer. The minimum size is 1024, and the maximum depends of
261 | * the output configuration.
262 | */
263 |
264 | #if VL53L8CX_MAX_RESULTS_SIZE < 1024U
265 | #define VL53L8CX_TEMPORARY_BUFFER_SIZE ((uint32_t) 1024U)
266 | #else
267 | #define VL53L8CX_TEMPORARY_BUFFER_SIZE ((uint32_t) VL53L8CX_MAX_RESULTS_SIZE)
268 | #endif
269 |
270 |
271 | /**
272 | * @brief Structure VL53L8CX_Configuration contains the sensor configuration.
273 | * User MUST not manually change these field, except for the sensor address.
274 | */
275 |
276 | typedef struct {
277 | /* Platform, filled by customer into the 'vl53l8cx_platform.h' file */
278 | VL53L8CX_Platform platform;
279 | /* Results streamcount, value auto-incremented at each range */
280 | uint8_t streamcount;
281 | /* Size of data read though I2C */
282 | uint32_t data_read_size;
283 | /* Address of default configuration buffer */
284 | uint8_t *default_configuration;
285 | /* Address of default Xtalk buffer */
286 | uint8_t *default_xtalk;
287 | /* Offset buffer */
288 | uint8_t offset_data[VL53L8CX_OFFSET_BUFFER_SIZE];
289 | /* Xtalk buffer */
290 | uint8_t xtalk_data[VL53L8CX_XTALK_BUFFER_SIZE];
291 | /* Temporary buffer used for internal driver processing */
292 | uint8_t temp_buffer[VL53L8CX_TEMPORARY_BUFFER_SIZE];
293 | /* Auto-stop flag for stopping the sensor */
294 | uint8_t is_auto_stop_enabled;
295 | } VL53L8CX_Configuration;
296 |
297 |
298 | /**
299 | * @brief Structure VL53L8CX_ResultsData contains the ranging results of
300 | * VL53L8CX. If user wants more than 1 target per zone, the results can be split
301 | * into 2 sub-groups :
302 | * - Per zone results. These results are common to all targets (ambient_per_spad
303 | * , nb_target_detected and nb_spads_enabled).
304 | * - Per target results : These results are different relative to the detected
305 | * target (signal_per_spad, range_sigma_mm, distance_mm, reflectance,
306 | * target_status).
307 | */
308 |
309 | typedef struct {
310 | /* Internal sensor silicon temperature */
311 | int8_t silicon_temp_degc;
312 |
313 | /* Ambient noise in kcps/spads */
314 | #ifndef VL53L8CX_DISABLE_AMBIENT_PER_SPAD
315 | uint32_t ambient_per_spad[VL53L8CX_RESOLUTION_8X8];
316 | #endif
317 |
318 | /* Number of valid target detected for 1 zone */
319 | #ifndef VL53L8CX_DISABLE_NB_TARGET_DETECTED
320 | uint8_t nb_target_detected[VL53L8CX_RESOLUTION_8X8];
321 | #endif
322 |
323 | /* Number of spads enabled for this ranging */
324 | #ifndef VL53L8CX_DISABLE_NB_SPADS_ENABLED
325 | uint32_t nb_spads_enabled[VL53L8CX_RESOLUTION_8X8];
326 | #endif
327 |
328 | /* Signal returned to the sensor in kcps/spads */
329 | #ifndef VL53L8CX_DISABLE_SIGNAL_PER_SPAD
330 | uint32_t signal_per_spad[(VL53L8CX_RESOLUTION_8X8
331 | *VL53L8CX_NB_TARGET_PER_ZONE)];
332 | #endif
333 |
334 | /* Sigma of the current distance in mm */
335 | #ifndef VL53L8CX_DISABLE_RANGE_SIGMA_MM
336 | uint16_t range_sigma_mm[(VL53L8CX_RESOLUTION_8X8
337 | *VL53L8CX_NB_TARGET_PER_ZONE)];
338 | #endif
339 |
340 | /* Measured distance in mm */
341 | #ifndef VL53L8CX_DISABLE_DISTANCE_MM
342 | int16_t distance_mm[(VL53L8CX_RESOLUTION_8X8
343 | *VL53L8CX_NB_TARGET_PER_ZONE)];
344 | #endif
345 |
346 | /* Estimated reflectance in percent */
347 | #ifndef VL53L8CX_DISABLE_REFLECTANCE_PERCENT
348 | uint8_t reflectance[(VL53L8CX_RESOLUTION_8X8
349 | *VL53L8CX_NB_TARGET_PER_ZONE)];
350 | #endif
351 |
352 | /* Status indicating the measurement validity (5 & 9 means ranging OK)*/
353 | #ifndef VL53L8CX_DISABLE_TARGET_STATUS
354 | uint8_t target_status[(VL53L8CX_RESOLUTION_8X8
355 | *VL53L8CX_NB_TARGET_PER_ZONE)];
356 | #endif
357 |
358 | /* Motion detector results */
359 | #ifndef VL53L8CX_DISABLE_MOTION_INDICATOR
360 | struct {
361 | uint32_t global_indicator_1;
362 | uint32_t global_indicator_2;
363 | uint8_t status;
364 | uint8_t nb_of_detected_aggregates;
365 | uint8_t nb_of_aggregates;
366 | uint8_t spare;
367 | uint32_t motion[32];
368 | } motion_indicator;
369 | #endif
370 |
371 | } VL53L8CX_ResultsData;
372 |
373 | #ifndef BLOCK_HEADER
374 | #define BLOCK_HEADER
375 | union Block_header {
376 | uint32_t bytes;
377 | struct {
378 | uint32_t type : 4;
379 | uint32_t size : 12;
380 | uint32_t idx : 16;
381 | };
382 | };
383 | #endif
384 |
385 | uint8_t vl53l8cx_is_alive(
386 | VL53L8CX_Configuration *p_dev,
387 | uint8_t *p_is_alive);
388 |
389 | /**
390 | * @brief Mandatory function used to initialize the sensor. This function must
391 | * be called after a power on, to load the firmware into the VL53L8CX. It takes
392 | * a few hundred milliseconds.
393 | * @param (VL53L8CX_Configuration) *p_dev : VL53L8CX configuration structure.
394 | * @return (uint8_t) status : 0 if initialization is OK.
395 | */
396 |
397 | uint8_t vl53l8cx_init(
398 | VL53L8CX_Configuration *p_dev);
399 |
400 | /**
401 | * @brief This function is used to change the I2C address of the sensor. If
402 | * multiple VL53L5 sensors are connected to the same I2C line, all other LPn
403 | * pins needs to be set to Low. The default sensor address is 0x52.
404 | * @param (VL53L8CX_Configuration) *p_dev : VL53L8CX configuration structure.
405 | * @param (uint16_t) i2c_address : New I2C address.
406 | * @return (uint8_t) status : 0 if new address is OK
407 | */
408 |
409 | uint8_t vl53l8cx_set_i2c_address(
410 | VL53L8CX_Configuration *p_dev,
411 | uint16_t i2c_address);
412 |
413 | /**
414 | * @brief This function is used to get the current sensor power mode.
415 | * @param (VL53L8CX_Configuration) *p_dev : VL53L8CX configuration structure.
416 | * @param (uint8_t) *p_power_mode : Current power mode. The value of this
417 | * pointer is equal to 0 if the sensor is in low power,
418 | * (VL53L8CX_POWER_MODE_SLEEP), or 1 if sensor is in standard mode
419 | * (VL53L8CX_POWER_MODE_WAKEUP).
420 | * @return (uint8_t) status : 0 if power mode is OK
421 | */
422 |
423 | uint8_t vl53l8cx_get_power_mode(
424 | VL53L8CX_Configuration *p_dev,
425 | uint8_t *p_power_mode);
426 |
427 | /**
428 | * @brief This function is used to set the sensor in Low Power mode, for
429 | * example if the sensor is not used during a long time. The macro
430 | * VL53L8CX_POWER_MODE_SLEEP can be used to enable the low power mode. When user
431 | * want to restart the sensor, he can use macro VL53L8CX_POWER_MODE_WAKEUP.
432 | * Please ensure that the device is not streaming before calling the function.
433 | * @param (VL53L8CX_Configuration) *p_dev : VL53L8CX configuration structure.
434 | * @param (uint8_t) power_mode : Selected power mode (VL53L8CX_POWER_MODE_SLEEP
435 | * or VL53L8CX_POWER_MODE_WAKEUP)
436 | * @return (uint8_t) status : 0 if power mode is OK, or 127 if power mode
437 | * requested by user is not valid.
438 | */
439 |
440 | uint8_t vl53l8cx_set_power_mode(
441 | VL53L8CX_Configuration *p_dev,
442 | uint8_t power_mode);
443 |
444 | /**
445 | * @brief This function starts a ranging session. When the sensor streams, host
446 | * cannot change settings 'on-the-fly'.
447 | * @param (VL53L8CX_Configuration) *p_dev : VL53L8CX configuration structure.
448 | * @return (uint8_t) status : 0 if start is OK.
449 | */
450 |
451 | uint8_t vl53l8cx_start_ranging(
452 | VL53L8CX_Configuration *p_dev);
453 |
454 | /**
455 | * @brief This function stops the ranging session. It must be used when the
456 | * sensor streams, after calling vl53l8cx_start_ranging().
457 | * @param (VL53L8CX_Configuration) *p_dev : VL53L8CX configuration structure.
458 | * @return (uint8_t) status : 0 if stop is OK
459 | */
460 |
461 | uint8_t vl53l8cx_stop_ranging(
462 | VL53L8CX_Configuration *p_dev);
463 |
464 | /**
465 | * @brief This function checks if a new data is ready by polling I2C. If a new
466 | * data is ready, a flag will be raised.
467 | * @param (VL53L8CX_Configuration) *p_dev : VL53L8CX configuration structure.
468 | * @param (uint8_t) *p_isReady : Value of this pointer be updated to 0 if data
469 | * is not ready, or 1 if a new data is ready.
470 | * @return (uint8_t) status : 0 if I2C reading is OK
471 | */
472 |
473 | uint8_t vl53l8cx_check_data_ready(
474 | VL53L8CX_Configuration *p_dev,
475 | uint8_t *p_isReady);
476 |
477 | /**
478 | * @brief This function gets the ranging data, using the selected output and the
479 | * resolution.
480 | * @param (VL53L8CX_Configuration) *p_dev : VL53L8CX configuration structure.
481 | * @param (VL53L8CX_ResultsData) *p_results : VL53L5 results structure.
482 | * @return (uint8_t) status : 0 data are successfully get.
483 | */
484 |
485 | uint8_t vl53l8cx_get_ranging_data(
486 | VL53L8CX_Configuration *p_dev,
487 | VL53L8CX_ResultsData *p_results);
488 |
489 | /**
490 | * @brief This function gets the current resolution (4x4 or 8x8).
491 | * @param (VL53L8CX_Configuration) *p_dev : VL53L8CX configuration structure.
492 | * @param (uint8_t) *p_resolution : Value of this pointer will be equal to 16
493 | * for 4x4 mode, and 64 for 8x8 mode.
494 | * @return (uint8_t) status : 0 if resolution is OK.
495 | */
496 |
497 | uint8_t vl53l8cx_get_resolution(
498 | VL53L8CX_Configuration *p_dev,
499 | uint8_t *p_resolution);
500 |
501 | /**
502 | * @brief This function sets a new resolution (4x4 or 8x8).
503 | * @param (VL53L8CX_Configuration) *p_dev : VL53L8CX configuration structure.
504 | * @param (uint8_t) resolution : Use macro VL53L8CX_RESOLUTION_4X4 or
505 | * VL53L8CX_RESOLUTION_8X8 to set the resolution.
506 | * @return (uint8_t) status : 0 if set resolution is OK.
507 | */
508 |
509 | uint8_t vl53l8cx_set_resolution(
510 | VL53L8CX_Configuration *p_dev,
511 | uint8_t resolution);
512 |
513 | /**
514 | * @brief This function gets the current ranging frequency in Hz. Ranging
515 | * frequency corresponds to the time between each measurement.
516 | * @param (VL53L8CX_Configuration) *p_dev : VL53L8CX configuration structure.
517 | * @param (uint8_t) *p_frequency_hz: Contains the ranging frequency in Hz.
518 | * @return (uint8_t) status : 0 if ranging frequency is OK.
519 | */
520 |
521 | uint8_t vl53l8cx_get_ranging_frequency_hz(
522 | VL53L8CX_Configuration *p_dev,
523 | uint8_t *p_frequency_hz);
524 |
525 | /**
526 | * @brief This function sets a new ranging frequency in Hz. Ranging frequency
527 | * corresponds to the measurements frequency. This setting depends of
528 | * the resolution, so please select your resolution before using this function.
529 | * @param (VL53L8CX_Configuration) *p_dev : VL53L8CX configuration structure.
530 | * @param (uint8_t) frequency_hz : Contains the ranging frequency in Hz.
531 | * - For 4x4, min and max allowed values are : [1;60]
532 | * - For 8x8, min and max allowed values are : [1;15]
533 | * @return (uint8_t) status : 0 if ranging frequency is OK, or 127 if the value
534 | * is not correct.
535 | */
536 |
537 | uint8_t vl53l8cx_set_ranging_frequency_hz(
538 | VL53L8CX_Configuration *p_dev,
539 | uint8_t frequency_hz);
540 |
541 | /**
542 | * @brief This function gets the current integration time in ms.
543 | * @param (VL53L8CX_Configuration) *p_dev : VL53L8CX configuration structure.
544 | * @param (uint32_t) *p_time_ms: Contains integration time in ms.
545 | * @return (uint8_t) status : 0 if integration time is OK.
546 | */
547 |
548 | uint8_t vl53l8cx_get_integration_time_ms(
549 | VL53L8CX_Configuration *p_dev,
550 | uint32_t *p_time_ms);
551 |
552 | /**
553 | * @brief This function sets a new integration time in ms. Integration time must
554 | * be computed to be lower than the ranging period, for a selected resolution.
555 | * Please note that this function has no impact on ranging mode continuous.
556 | * @param (VL53L8CX_Configuration) *p_dev : VL53L8CX configuration structure.
557 | * @param (uint32_t) time_ms : Contains the integration time in ms. For all
558 | * resolutions and frequency, the minimum value is 2ms, and the maximum is
559 | * 1000ms.
560 | * @return (uint8_t) status : 0 if set integration time is OK.
561 | */
562 |
563 | uint8_t vl53l8cx_set_integration_time_ms(
564 | VL53L8CX_Configuration *p_dev,
565 | uint32_t integration_time_ms);
566 |
567 | /**
568 | * @brief This function gets the current sharpener in percent. Sharpener can be
569 | * changed to blur more or less zones depending of the application.
570 | * @param (VL53L8CX_Configuration) *p_dev : VL53L8CX configuration structure.
571 | * @param (uint32_t) *p_sharpener_percent: Contains the sharpener in percent.
572 | * @return (uint8_t) status : 0 if get sharpener is OK.
573 | */
574 |
575 | uint8_t vl53l8cx_get_sharpener_percent(
576 | VL53L8CX_Configuration *p_dev,
577 | uint8_t *p_sharpener_percent);
578 |
579 | /**
580 | * @brief This function sets a new sharpener value in percent. Sharpener can be
581 | * changed to blur more or less zones depending of the application. Min value is
582 | * 0 (disabled), and max is 99.
583 | * @param (VL53L8CX_Configuration) *p_dev : VL53L8CX configuration structure.
584 | * @param (uint32_t) sharpener_percent : Value between 0 (disabled) and 99%.
585 | * @return (uint8_t) status : 0 if set sharpener is OK.
586 | */
587 |
588 | uint8_t vl53l8cx_set_sharpener_percent(
589 | VL53L8CX_Configuration *p_dev,
590 | uint8_t sharpener_percent);
591 |
592 | /**
593 | * @brief This function gets the current target order (closest or strongest).
594 | * @param (VL53L8CX_Configuration) *p_dev : VL53L8CX configuration structure.
595 | * @param (uint8_t) *p_target_order: Contains the target order.
596 | * @return (uint8_t) status : 0 if get target order is OK.
597 | */
598 |
599 | uint8_t vl53l8cx_get_target_order(
600 | VL53L8CX_Configuration *p_dev,
601 | uint8_t *p_target_order);
602 |
603 | /**
604 | * @brief This function sets a new target order. Please use macros
605 | * VL53L8CX_TARGET_ORDER_STRONGEST and VL53L8CX_TARGET_ORDER_CLOSEST to define
606 | * the new output order. By default, the sensor is configured with the strongest
607 | * output.
608 | * @param (VL53L8CX_Configuration) *p_dev : VL53L8CX configuration structure.
609 | * @param (uint8_t) target_order : Required target order.
610 | * @return (uint8_t) status : 0 if set target order is OK, or 127 if target
611 | * order is unknown.
612 | */
613 |
614 | uint8_t vl53l8cx_set_target_order(
615 | VL53L8CX_Configuration *p_dev,
616 | uint8_t target_order);
617 |
618 | /**
619 | * @brief This function is used to get the ranging mode. Two modes are
620 | * available using ULD : Continuous and autonomous. The default
621 | * mode is Autonomous.
622 | * @param (VL53L8CX_Configuration) *p_dev : VL53L8CX configuration structure.
623 | * @param (uint8_t) *p_ranging_mode : current ranging mode
624 | * @return (uint8_t) status : 0 if get ranging mode is OK.
625 | */
626 |
627 | uint8_t vl53l8cx_get_ranging_mode(
628 | VL53L8CX_Configuration *p_dev,
629 | uint8_t *p_ranging_mode);
630 |
631 | /**
632 | * @brief This function is used to set the ranging mode. Two modes are
633 | * available using ULD : Continuous and autonomous. The default
634 | * mode is Autonomous.
635 | * @param (VL53L8CX_Configuration) *p_dev : VL53L8CX configuration structure.
636 | * @param (uint8_t) ranging_mode : Use macros VL53L8CX_RANGING_MODE_CONTINUOUS,
637 | * VL53L8CX_RANGING_MODE_CONTINUOUS.
638 | * @return (uint8_t) status : 0 if set ranging mode is OK.
639 | */
640 |
641 | uint8_t vl53l8cx_set_ranging_mode(
642 | VL53L8CX_Configuration *p_dev,
643 | uint8_t ranging_mode);
644 |
645 | /**
646 | * @brief This function is used to check if the synchronization pin is enabled
647 | * or disabled. When it is enabled, the sensor waits an interrupt on B1 pin
648 | * to start the next measurement. It is useful for multi-devices
649 | * synchronization. By default the sync pin is disabled.
650 | * @param (VL53L8CX_Configuration) *p_dev : VL53L8CX configuration structure.
651 | * @param (uint8_t*) p_is_sync_pin_enabled : Pointer of sync pin status. Value
652 | * overridden to 0 if the pin is disabled, or 1 if the pin is enabled.
653 | * @return (uint8_t) status : 0 if get sync pin OK.
654 | */
655 | uint8_t vl53l8cx_get_external_sync_pin_enable(
656 | VL53L8CX_Configuration *p_dev,
657 | uint8_t *p_is_sync_pin_enabled);
658 |
659 |
660 | /**
661 | * @brief This function is used to enable or disable the synchronization pin. When
662 | * it is enabled, the sensor waits an interrupt on B1 pin to start the next
663 | * measurement. It is useful for multi-devices synchronization. By default the sync
664 | * pin is disabled.
665 | * @param (VL53L8CX_Configuration) *p_dev : VL53L8CX configuration structure.
666 | * @param (uint8_t) enable_sync_pin : Ste the value to 1 to enable the sync
667 | * pin, or 0 to disable it.
668 | * @return (uint8_t) status : 0 if set sync pin OK.
669 | */
670 | uint8_t vl53l8cx_set_external_sync_pin_enable(
671 | VL53L8CX_Configuration *p_dev,
672 | uint8_t enable_sync_pin);
673 |
674 | /**
675 | * @brief This function is used to get the number of frames between 2 temperature
676 | * compensation.
677 | * @param (VL53L8CX_Configuration) *p_dev : VL53L8CX configuration structure.
678 | * @param (uint32_t) *p_repeat_count : Number of frames before next temperature
679 | * compensation. Set to 0 to disable the feature (default configuration).
680 | */
681 | uint8_t vl53l8cx_get_VHV_repeat_count(
682 | VL53L8CX_Configuration *p_dev,
683 | uint32_t *p_repeat_count);
684 |
685 | /**
686 | * @brief This function is used to set a periodic temperature compensation. By
687 | * setting a repeat count different to 0 the firmware automatically runs a
688 | * temperature calibration every N frames.
689 | * default the repeat count is set to 0
690 | * @param (VL53L8CX_Configuration) *p_dev : VL53L8CX configuration structure.
691 | * @param (uint32_t) repeat_count : Number of frames between temperature
692 | * compensation. Set to 0 to disable the feature (default configuration).
693 | */
694 | uint8_t vl53l8cx_set_VHV_repeat_count(
695 | VL53L8CX_Configuration *p_dev,
696 | uint32_t repeat_count);
697 |
698 | /**
699 | * @brief This function can be used to read 'extra data' from DCI. Using a known
700 | * index, the function fills the casted structure passed in argument.
701 | * @param (VL53L8CX_Configuration) *p_dev : VL53L8CX configuration structure.
702 | * @param (uint8_t) *data : This field can be a casted structure, or a simple
703 | * array. Please note that the FW only accept data of 32 bits. So field data can
704 | * only have a size of 32, 64, 96, 128, bits ....
705 | * @param (uint32_t) index : Index of required value.
706 | * @param (uint16_t)*data_size : This field must be the structure or array size
707 | * (using sizeof() function).
708 | * @return (uint8_t) status : 0 if OK
709 | */
710 |
711 | uint8_t vl53l8cx_dci_read_data(
712 | VL53L8CX_Configuration *p_dev,
713 | uint8_t *data,
714 | uint32_t index,
715 | uint16_t data_size);
716 |
717 | /**
718 | * @brief This function can be used to write 'extra data' to DCI. The data can
719 | * be simple data, or casted structure.
720 | * @param (VL53L8CX_Configuration) *p_dev : VL53L8CX configuration structure.
721 | * @param (uint8_t) *data : This field can be a casted structure, or a simple
722 | * array. Please note that the FW only accept data of 32 bits. So field data can
723 | * only have a size of 32, 64, 96, 128, bits ..
724 | * @param (uint32_t) index : Index of required value.
725 | * @param (uint16_t)*data_size : This field must be the structure or array size
726 | * (using sizeof() function).
727 | * @return (uint8_t) status : 0 if OK
728 | */
729 |
730 | uint8_t vl53l8cx_dci_write_data(
731 | VL53L8CX_Configuration *p_dev,
732 | uint8_t *data,
733 | uint32_t index,
734 | uint16_t data_size);
735 |
736 | /**
737 | * @brief This function can be used to replace 'extra data' in DCI. The data can
738 | * be simple data, or casted structure.
739 | * @param (VL53L8CX_Configuration) *p_dev : VL53L8CX configuration structure.
740 | * @param (uint8_t) *data : This field can be a casted structure, or a simple
741 | * array. Please note that the FW only accept data of 32 bits. So field data can
742 | * only have a size of 32, 64, 96, 128, bits ..
743 | * @param (uint32_t) index : Index of required value.
744 | * @param (uint16_t)*data_size : This field must be the structure or array size
745 | * (using sizeof() function).
746 | * @param (uint8_t) *new_data : Contains the new fields.
747 | * @param (uint16_t) new_data_size : New data size.
748 | * @param (uint16_t) new_data_pos : New data position into the buffer.
749 | * @return (uint8_t) status : 0 if OK
750 | */
751 |
752 | uint8_t vl53l8cx_dci_replace_data(
753 | VL53L8CX_Configuration *p_dev,
754 | uint8_t *data,
755 | uint32_t index,
756 | uint16_t data_size,
757 | uint8_t *new_data,
758 | uint16_t new_data_size,
759 | uint16_t new_data_pos);
760 |
761 | #ifdef __cplusplus
762 | }
763 | #endif
764 |
765 | #endif //VL53L8CX_API_H_
766 |
--------------------------------------------------------------------------------
/src/vl53l8cx_platform.c:
--------------------------------------------------------------------------------
1 | /**
2 | ******************************************************************************
3 | * @file vl53l8cx_platform.cpp
4 | * @author STMicroelectronics
5 | * @version V1.0.0
6 | * @date 11 November 2021
7 | * @brief Implementation of the platform dependent APIs.
8 | ******************************************************************************
9 | * @attention
10 | *
11 | * © COPYRIGHT(c) 2021 STMicroelectronics
12 | *
13 | * Redistribution and use in source and binary forms, with or without modification,
14 | * are permitted provided that the following conditions are met:
15 | * 1. Redistributions of source code must retain the above copyright notice,
16 | * this list of conditions and the following disclaimer.
17 | * 2. Redistributions in binary form must reproduce the above copyright notice,
18 | * this list of conditions and the following disclaimer in the documentation
19 | * and/or other materials provided with the distribution.
20 | * 3. Neither the name of STMicroelectronics nor the names of its contributors
21 | * may be used to endorse or promote products derived from this software
22 | * without specific prior written permission.
23 | *
24 | * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
25 | * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
26 | * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
27 | * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
28 | * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
29 | * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
30 | * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
31 | * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
32 | * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
33 | * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
34 | *
35 | ******************************************************************************
36 | */
37 |
38 |
39 | #include "vl53l8cx_platform.h"
40 |
41 |
42 | uint8_t VL53L8CX_RdByte(
43 | VL53L8CX_Platform *p_platform,
44 | uint16_t RegisterAdress,
45 | uint8_t *p_value)
46 | {
47 | return p_platform->Read(p_platform->handle, RegisterAdress, p_value, 1U);
48 | }
49 |
50 | uint8_t VL53L8CX_WrByte(
51 | VL53L8CX_Platform *p_platform,
52 | uint16_t RegisterAdress,
53 | uint8_t value)
54 | {
55 | return p_platform->Write(p_platform->handle, RegisterAdress, &value, 1U);
56 | }
57 |
58 | uint8_t VL53L8CX_WrMulti(
59 | VL53L8CX_Platform *p_platform,
60 | uint16_t RegisterAdress,
61 | uint8_t *p_values,
62 | uint32_t size)
63 | {
64 | return p_platform->Write(p_platform->handle, RegisterAdress, p_values, size);
65 | }
66 |
67 | uint8_t VL53L8CX_RdMulti(
68 | VL53L8CX_Platform *p_platform,
69 | uint16_t RegisterAdress,
70 | uint8_t *p_values,
71 | uint32_t size)
72 | {
73 | return p_platform->Read(p_platform->handle, RegisterAdress, p_values, size);
74 | }
75 |
76 | void VL53L8CX_SwapBuffer(
77 | uint8_t *buffer,
78 | uint16_t size)
79 | {
80 | uint32_t i, tmp;
81 |
82 | /* Example of possible implementation using */
83 | for (i = 0; i < size; i = i + 4) {
84 | tmp = (
85 | buffer[i] << 24)
86 | | (buffer[i + 1] << 16)
87 | | (buffer[i + 2] << 8)
88 | | (buffer[i + 3]);
89 |
90 | memcpy(&(buffer[i]), &tmp, 4);
91 | }
92 | }
93 |
94 | uint8_t VL53L8CX_WaitMs(
95 | VL53L8CX_Platform *p_platform,
96 | uint32_t TimeMs)
97 | {
98 | return p_platform->Wait(p_platform->handle, TimeMs);
99 | }
100 |
--------------------------------------------------------------------------------
/src/vl53l8cx_platform.h:
--------------------------------------------------------------------------------
1 | /**
2 | ******************************************************************************
3 | * @file vl53l8cx_platform.h
4 | * @author STMicroelectronics
5 | * @version V1.0.0
6 | * @date 11 November 2021
7 | * @brief Header file of the platform dependent structures.
8 | ******************************************************************************
9 | * @attention
10 | *
11 | * © COPYRIGHT(c) 2021 STMicroelectronics
12 | *
13 | * Redistribution and use in source and binary forms, with or without modification,
14 | * are permitted provided that the following conditions are met:
15 | * 1. Redistributions of source code must retain the above copyright notice,
16 | * this list of conditions and the following disclaimer.
17 | * 2. Redistributions in binary form must reproduce the above copyright notice,
18 | * this list of conditions and the following disclaimer in the documentation
19 | * and/or other materials provided with the distribution.
20 | * 3. Neither the name of STMicroelectronics nor the names of its contributors
21 | * may be used to endorse or promote products derived from this software
22 | * without specific prior written permission.
23 | *
24 | * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
25 | * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
26 | * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
27 | * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
28 | * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
29 | * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
30 | * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
31 | * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
32 | * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
33 | * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
34 | *
35 | ******************************************************************************
36 | */
37 |
38 | #ifndef _VL53L8CX_PLATFORM_H_
39 | #define _VL53L8CX_PLATFORM_H_
40 |
41 | #ifdef __cplusplus
42 | extern "C" {
43 | #endif
44 |
45 |
46 | #pragma once
47 |
48 | #include
49 | #include
50 | #include "vl53l8cx_platform_config.h"
51 |
52 | #define VL53L8CX_COMMS_CHUNK_SIZE 4096
53 | #define SPI_WRITE_MASK(x) (uint16_t)(x | 0x8000)
54 | #define SPI_READ_MASK(x) (uint16_t)(x & ~0x8000)
55 |
56 | typedef uint8_t (*VL53L8CX_wait_Func)(void *, uint32_t);
57 | typedef uint8_t (*VL53L8CX_write_Func)(void *, uint16_t, uint8_t *, uint32_t);
58 | typedef uint8_t (*VL53L8CX_read_Func)(void *, uint16_t, uint8_t *, uint32_t);
59 |
60 | #ifndef DEFAULT_I2C_BUFFER_LEN
61 | #ifdef ARDUINO_SAM_DUE
62 | /* FIXME: It seems that an I2C buffer of BUFFER_LENGTH does not work on Arduino DUE. So, we need to decrease the size */
63 | #define DEFAULT_I2C_BUFFER_LEN (BUFFER_LENGTH - 2)
64 | #else
65 | #ifdef BUFFER_LENGTH
66 | #define DEFAULT_I2C_BUFFER_LEN BUFFER_LENGTH
67 | #else
68 | #define DEFAULT_I2C_BUFFER_LEN 32
69 | #endif
70 | #endif
71 | #endif
72 | typedef struct {
73 | uint16_t address;
74 | VL53L8CX_write_Func Write;
75 | VL53L8CX_read_Func Read;
76 | VL53L8CX_wait_Func Wait;
77 | void *handle;
78 | } VL53L8CX_Platform;
79 |
80 |
81 | uint8_t VL53L8CX_RdByte(
82 | VL53L8CX_Platform *p_platform,
83 | uint16_t RegisterAddress,
84 | uint8_t *p_value);
85 |
86 | uint8_t VL53L8CX_WrByte(
87 | VL53L8CX_Platform *p_platform,
88 | uint16_t RegisterAddress,
89 | uint8_t value);
90 |
91 | uint8_t VL53L8CX_WrMulti(
92 | VL53L8CX_Platform *p_platform,
93 | uint16_t RegisterAddress,
94 | uint8_t *p_values,
95 | uint32_t size);
96 |
97 | uint8_t VL53L8CX_RdMulti(
98 | VL53L8CX_Platform *p_platform,
99 | uint16_t RegisterAddress,
100 | uint8_t *p_values,
101 | uint32_t size);
102 |
103 | uint8_t VL53L8CX_WaitMs(
104 | VL53L8CX_Platform *p_platform,
105 | uint32_t TimeMs);
106 | void VL53L8CX_SwapBuffer(
107 | uint8_t *buffer,
108 | uint16_t size);
109 |
110 | #ifdef __cplusplus
111 | }
112 | #endif
113 |
114 | #endif // _VL53L8CX_PLATFORM_H_
115 |
--------------------------------------------------------------------------------
/src/vl53l8cx_platform_config.h:
--------------------------------------------------------------------------------
1 | /**
2 | ******************************************************************************
3 | * @file vl53l8cx_platform_config.h
4 | * @author STMicroelectronics
5 | * @version V1.0.0
6 | * @date 11 November 2021
7 | * @brief Header file for the platform settings.
8 | ******************************************************************************
9 | * @attention
10 | *
11 | * © COPYRIGHT(c) 2021 STMicroelectronics
12 | *
13 | * Redistribution and use in source and binary forms, with or without modification,
14 | * are permitted provided that the following conditions are met:
15 | * 1. Redistributions of source code must retain the above copyright notice,
16 | * this list of conditions and the following disclaimer.
17 | * 2. Redistributions in binary form must reproduce the above copyright notice,
18 | * this list of conditions and the following disclaimer in the documentation
19 | * and/or other materials provided with the distribution.
20 | * 3. Neither the name of STMicroelectronics nor the names of its contributors
21 | * may be used to endorse or promote products derived from this software
22 | * without specific prior written permission.
23 | *
24 | * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
25 | * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
26 | * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
27 | * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
28 | * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
29 | * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
30 | * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
31 | * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
32 | * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
33 | * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
34 | *
35 | ******************************************************************************
36 | */
37 |
38 | #ifndef _VL53L8CX_PLATFORM_CONFIG_H_
39 | #define _VL53L8CX_PLATFORM_CONFIG_H_
40 |
41 | #if __has_include("vl53l8cx_platform_config_custom.h")
42 | #include "vl53l8cx_platform_config_custom.h"
43 | #else
44 | #include "vl53l8cx_platform_config_default.h"
45 | #endif
46 |
47 | #endif // _VL53L8CX_PLATFORM_CONFIG_H_
48 |
--------------------------------------------------------------------------------
/src/vl53l8cx_platform_config_default.h:
--------------------------------------------------------------------------------
1 | /**
2 | ******************************************************************************
3 | * @file vl53l8cx_platform_config_default.h
4 | * @author STMicroelectronics
5 | * @version V1.0.0
6 | * @date 11 November 2021
7 | * @brief Header file with the default platform settings.
8 | ******************************************************************************
9 | * @attention
10 | *
11 | * © COPYRIGHT(c) 2021 STMicroelectronics
12 | *
13 | * Redistribution and use in source and binary forms, with or without modification,
14 | * are permitted provided that the following conditions are met:
15 | * 1. Redistributions of source code must retain the above copyright notice,
16 | * this list of conditions and the following disclaimer.
17 | * 2. Redistributions in binary form must reproduce the above copyright notice,
18 | * this list of conditions and the following disclaimer in the documentation
19 | * and/or other materials provided with the distribution.
20 | * 3. Neither the name of STMicroelectronics nor the names of its contributors
21 | * may be used to endorse or promote products derived from this software
22 | * without specific prior written permission.
23 | *
24 | * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
25 | * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
26 | * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
27 | * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
28 | * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
29 | * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
30 | * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
31 | * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
32 | * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
33 | * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
34 | *
35 | ******************************************************************************
36 | */
37 |
38 | #ifndef _VL53L8CX_PLATFORM_CONFIG_DEFAULT_H_
39 | #define _VL53L8CX_PLATFORM_CONFIG_DEFAULT_H_
40 |
41 | /*
42 | * @brief If you want to customize these defines you can add in the application
43 | * code the file platform_config_custom.h file where you can override some of
44 | * these defines.
45 | */
46 |
47 | /*
48 | * @brief The macro below is used to define the number of target per zone sent
49 | * through I2C. This value can be changed by user, in order to tune I2C
50 | * transaction, and also the total memory size (a lower number of target per
51 | * zone means a lower RAM). The value must be between 1 and 4.
52 | */
53 |
54 | #ifndef VL53L8CX_NB_TARGET_PER_ZONE
55 | #define VL53L8CX_NB_TARGET_PER_ZONE 1U
56 | #endif
57 |
58 | /*
59 | * @brief The macro below can be used to avoid data conversion into the driver.
60 | * By default there is a conversion between firmware and user data. Using this macro
61 | * allows to use the firmware format instead of user format. The firmware format allows
62 | * an increased precision.
63 | */
64 |
65 | // #define VL53L8CX_USE_RAW_FORMAT
66 |
67 | /*
68 | * @brief All macro below are used to configure the sensor output. User can
69 | * define some macros if he wants to disable selected output, in order to reduce
70 | * I2C access.
71 | */
72 |
73 | // #define VL53L8CX_DISABLE_AMBIENT_PER_SPAD
74 | // #define VL53L8CX_DISABLE_NB_SPADS_ENABLED
75 | // #define VL53L8CX_DISABLE_NB_TARGET_DETECTED
76 | // #define VL53L8CX_DISABLE_SIGNAL_PER_SPAD
77 | // #define VL53L8CX_DISABLE_RANGE_SIGMA_MM
78 | // #define VL53L8CX_DISABLE_DISTANCE_MM
79 | // #define VL53L8CX_DISABLE_REFLECTANCE_PERCENT
80 | // #define VL53L8CX_DISABLE_TARGET_STATUS
81 | // #define VL53L8CX_DISABLE_MOTION_INDICATOR
82 |
83 | #endif // _VL53L8CX_PLATFORM_CONFIG_DEFAULT_H_
84 |
--------------------------------------------------------------------------------
/src/vl53l8cx_plugin_detection_thresholds.c:
--------------------------------------------------------------------------------
1 | /**
2 | *
3 | * Copyright (c) 2021 STMicroelectronics.
4 | * All rights reserved.
5 | *
6 | * This software is licensed under terms that can be found in the LICENSE file
7 | * in the root directory of this software component.
8 | * If no LICENSE file comes with this software, it is provided AS-IS.
9 | *
10 | ******************************************************************************
11 | */
12 |
13 | #include "vl53l8cx_plugin_detection_thresholds.h"
14 |
15 | uint8_t vl53l8cx_get_detection_thresholds_enable(
16 | VL53L8CX_Configuration *p_dev,
17 | uint8_t *p_enabled)
18 | {
19 | uint8_t status = VL53L8CX_STATUS_OK;
20 |
21 | status |= vl53l8cx_dci_read_data(p_dev, (uint8_t *)p_dev->temp_buffer,
22 | VL53L8CX_DCI_DET_THRESH_GLOBAL_CONFIG, 8);
23 | *p_enabled = p_dev->temp_buffer[0x1];
24 |
25 | return status;
26 | }
27 |
28 | uint8_t vl53l8cx_set_detection_thresholds_enable(
29 | VL53L8CX_Configuration *p_dev,
30 | uint8_t enabled)
31 | {
32 | uint8_t tmp, status = VL53L8CX_STATUS_OK;
33 | uint8_t grp_global_config[] = {0x01, 0x00, 0x01, 0x00};
34 |
35 | if (enabled == (uint8_t)1) {
36 | grp_global_config[0x01] = 0x01;
37 | tmp = 0x04;
38 | } else {
39 | grp_global_config[0x01] = 0x00;
40 | tmp = 0x0C;
41 | }
42 |
43 | /* Set global interrupt config */
44 | status |= vl53l8cx_dci_replace_data(p_dev, p_dev->temp_buffer,
45 | VL53L8CX_DCI_DET_THRESH_GLOBAL_CONFIG, 8,
46 | (uint8_t *)&grp_global_config, 4, 0x00);
47 |
48 | /* Update interrupt config */
49 | status |= vl53l8cx_dci_replace_data(p_dev, p_dev->temp_buffer,
50 | VL53L8CX_DCI_DET_THRESH_CONFIG, 20,
51 | (uint8_t *)&tmp, 1, 0x11);
52 |
53 | return status;
54 | }
55 |
56 | uint8_t vl53l8cx_get_detection_thresholds(
57 | VL53L8CX_Configuration *p_dev,
58 | VL53L8CX_DetectionThresholds *p_thresholds)
59 | {
60 | uint8_t i, status = VL53L8CX_STATUS_OK;
61 |
62 | /* Get thresholds configuration */
63 | status |= vl53l8cx_dci_read_data(p_dev, (uint8_t *)p_thresholds,
64 | VL53L8CX_DCI_DET_THRESH_START,
65 | (uint16_t)VL53L8CX_NB_THRESHOLDS
66 | * (uint16_t)sizeof(VL53L8CX_DetectionThresholds));
67 |
68 | for (i = 0; i < (uint8_t)VL53L8CX_NB_THRESHOLDS; i++) {
69 | switch (p_thresholds[i].measurement) {
70 | case VL53L8CX_DISTANCE_MM:
71 | p_thresholds[i].param_low_thresh /= 4;
72 | p_thresholds[i].param_high_thresh /= 4;
73 | break;
74 | case VL53L8CX_SIGNAL_PER_SPAD_KCPS:
75 | p_thresholds[i].param_low_thresh /= 2048;
76 | p_thresholds[i].param_high_thresh /= 2048;
77 | break;
78 | case VL53L8CX_RANGE_SIGMA_MM:
79 | p_thresholds[i].param_low_thresh /= 128;
80 | p_thresholds[i].param_high_thresh /= 128;
81 | break;
82 | case VL53L8CX_AMBIENT_PER_SPAD_KCPS:
83 | p_thresholds[i].param_low_thresh /= 2048;
84 | p_thresholds[i].param_high_thresh /= 2048;
85 | break;
86 | case VL53L8CX_NB_SPADS_ENABLED:
87 | p_thresholds[i].param_low_thresh /= 256;
88 | p_thresholds[i].param_high_thresh /= 256;
89 | break;
90 | case VL53L8CX_MOTION_INDICATOR:
91 | p_thresholds[i].param_low_thresh /= 65535;
92 | p_thresholds[i].param_high_thresh /= 65535;
93 | break;
94 | default:
95 | break;
96 | }
97 | }
98 |
99 | return status;
100 | }
101 |
102 | uint8_t vl53l8cx_set_detection_thresholds(
103 | VL53L8CX_Configuration *p_dev,
104 | VL53L8CX_DetectionThresholds *p_thresholds)
105 | {
106 | uint8_t i, status = VL53L8CX_STATUS_OK;
107 | uint8_t grp_valid_target_cfg[] = {0x05, 0x05, 0x05, 0x05,
108 | 0x05, 0x05, 0x05, 0x05
109 | };
110 |
111 | for (i = 0; i < (uint8_t) VL53L8CX_NB_THRESHOLDS; i++) {
112 | switch (p_thresholds->measurement) {
113 | case VL53L8CX_DISTANCE_MM:
114 | p_thresholds[i].param_low_thresh *= 4;
115 | p_thresholds[i].param_high_thresh *= 4;
116 | break;
117 | case VL53L8CX_SIGNAL_PER_SPAD_KCPS:
118 | p_thresholds[i].param_low_thresh *= 2048;
119 | p_thresholds[i].param_high_thresh *= 2048;
120 | break;
121 | case VL53L8CX_RANGE_SIGMA_MM:
122 | p_thresholds[i].param_low_thresh *= 128;
123 | p_thresholds[i].param_high_thresh *= 128;
124 | break;
125 | case VL53L8CX_AMBIENT_PER_SPAD_KCPS:
126 | p_thresholds[i].param_low_thresh *= 2048;
127 | p_thresholds[i].param_high_thresh *= 2048;
128 | break;
129 | case VL53L8CX_NB_SPADS_ENABLED:
130 | p_thresholds[i].param_low_thresh *= 256;
131 | p_thresholds[i].param_high_thresh *= 256;
132 | break;
133 | case VL53L8CX_MOTION_INDICATOR:
134 | p_thresholds[i].param_low_thresh *= 65535;
135 | p_thresholds[i].param_high_thresh *= 65535;
136 | break;
137 | default:
138 | break;
139 | }
140 | }
141 |
142 | /* Set valid target list */
143 | status |= vl53l8cx_dci_write_data(p_dev, (uint8_t *)grp_valid_target_cfg,
144 | VL53L8CX_DCI_DET_THRESH_VALID_STATUS,
145 | (uint16_t)sizeof(grp_valid_target_cfg));
146 |
147 | /* Set thresholds configuration */
148 | status |= vl53l8cx_dci_write_data(p_dev, (uint8_t *)p_thresholds,
149 | VL53L8CX_DCI_DET_THRESH_START,
150 | (uint16_t)(VL53L8CX_NB_THRESHOLDS
151 | * sizeof(VL53L8CX_DetectionThresholds)));
152 |
153 | return status;
154 | }
155 |
156 | uint8_t vl53l8cx_get_detection_thresholds_auto_stop(
157 | VL53L8CX_Configuration *p_dev,
158 | uint8_t *p_auto_stop)
159 | {
160 | uint8_t status = VL53L8CX_STATUS_OK;
161 |
162 | status |= vl53l8cx_dci_read_data(p_dev, (uint8_t *)p_dev->temp_buffer,
163 | VL53L8CX_DCI_PIPE_CONTROL, 4);
164 | *p_auto_stop = p_dev->temp_buffer[0x3];
165 |
166 | return status;
167 | }
168 |
169 | uint8_t vl53l8cx_set_detection_thresholds_auto_stop(
170 | VL53L8CX_Configuration *p_dev,
171 | uint8_t auto_stop)
172 | {
173 | uint8_t status = VL53L8CX_STATUS_OK;
174 |
175 | status |= vl53l8cx_dci_replace_data(p_dev, p_dev->temp_buffer,
176 | VL53L8CX_DCI_PIPE_CONTROL, 4,
177 | (uint8_t *)&auto_stop, 1, 0x03);
178 | p_dev->is_auto_stop_enabled = (uint8_t)auto_stop;
179 |
180 | return status;
181 | }
182 |
--------------------------------------------------------------------------------
/src/vl53l8cx_plugin_detection_thresholds.h:
--------------------------------------------------------------------------------
1 | /**
2 | *
3 | * Copyright (c) 2021 STMicroelectronics.
4 | * All rights reserved.
5 | *
6 | * This software is licensed under terms that can be found in the LICENSE file
7 | * in the root directory of this software component.
8 | * If no LICENSE file comes with this software, it is provided AS-IS.
9 | *
10 | ******************************************************************************
11 | */
12 |
13 | #ifndef VL53L8CX_PLUGIN_DETECTION_THRESHOLDS_H_
14 | #define VL53L8CX_PLUGIN_DETECTION_THRESHOLDS_H_
15 |
16 | #ifdef __cplusplus
17 | extern "C" {
18 | #endif
19 |
20 | #include "vl53l8cx_api.h"
21 |
22 | /**
23 | * @brief Macro VL53L8CX_NB_THRESHOLDS indicates the number of checkers. This
24 | * value cannot be changed.
25 | */
26 |
27 | #define VL53L8CX_NB_THRESHOLDS ((uint8_t)64U)
28 |
29 | /**
30 | * @brief Inner Macro for API. Not for user, only for development.
31 | */
32 |
33 | #define VL53L8CX_DCI_DET_THRESH_CONFIG ((uint16_t)0x5488U)
34 | #define VL53L8CX_DCI_DET_THRESH_GLOBAL_CONFIG ((uint16_t)0xB6E0U)
35 | #define VL53L8CX_DCI_DET_THRESH_START ((uint16_t)0xB6E8U)
36 | #define VL53L8CX_DCI_DET_THRESH_VALID_STATUS ((uint16_t)0xB9F0U)
37 |
38 | /**
39 | * @brief Macro VL53L8CX_LAST_THRESHOLD is used to indicate the end of checkers
40 | * programming.
41 | */
42 |
43 | #define VL53L8CX_LAST_THRESHOLD ((uint8_t)128U)
44 |
45 | /**
46 | * @brief The following macro are used to define the 'param_type' of a checker.
47 | * They indicate what is the measurement to catch.
48 | */
49 |
50 | #define VL53L8CX_DISTANCE_MM ((uint8_t)1U)
51 | #define VL53L8CX_SIGNAL_PER_SPAD_KCPS ((uint8_t)2U)
52 | #define VL53L8CX_RANGE_SIGMA_MM ((uint8_t)4U)
53 | #define VL53L8CX_AMBIENT_PER_SPAD_KCPS ((uint8_t)8U)
54 | #define VL53L8CX_NB_TARGET_DETECTED ((uint8_t)9U)
55 | #define VL53L8CX_TARGET_STATUS ((uint8_t)12U)
56 | #define VL53L8CX_NB_SPADS_ENABLED ((uint8_t)13U)
57 | #define VL53L8CX_MOTION_INDICATOR ((uint8_t)19U)
58 |
59 | /**
60 | * @brief The following macro are used to define the 'type' of a checker.
61 | * They indicate the window of measurements, defined by low and a high
62 | * thresholds.
63 | */
64 |
65 | #define VL53L8CX_IN_WINDOW ((uint8_t)0U)
66 | #define VL53L8CX_OUT_OF_WINDOW ((uint8_t)1U)
67 | #define VL53L8CX_LESS_THAN_EQUAL_MIN_CHECKER ((uint8_t)2U)
68 | #define VL53L8CX_GREATER_THAN_MAX_CHECKER ((uint8_t)3U)
69 | #define VL53L8CX_EQUAL_MIN_CHECKER ((uint8_t)4U)
70 | #define VL53L8CX_NOT_EQUAL_MIN_CHECKER ((uint8_t)5U)
71 |
72 | /**
73 | * @brief The following macro are used to define multiple checkers in the same
74 | * zone, using operators. Please note that the first checker MUST always be a OR
75 | * operation.
76 | */
77 |
78 | #define VL53L8CX_OPERATION_NONE ((uint8_t)0U)
79 | #define VL53L8CX_OPERATION_OR ((uint8_t)0U)
80 | #define VL53L8CX_OPERATION_AND ((uint8_t)2U)
81 |
82 | /**
83 | * @brief Structure VL53L8CX_DetectionThresholds contains a single threshold.
84 | * This structure is never used alone, it must be used as an array of 64
85 | * thresholds (defined by macro VL53L8CX_NB_THRESHOLDS).
86 | */
87 |
88 | typedef struct {
89 |
90 | /* Low threshold */
91 | int32_t param_low_thresh;
92 | /* High threshold */
93 | int32_t param_high_thresh;
94 | /* Measurement to catch (VL53L8CX_MEDIAN_RANGE_MM,...)*/
95 | uint8_t measurement;
96 | /* Windows type (VL53L8CX_IN_WINDOW, VL53L8CX_OUT_WINDOW, ...) */
97 | uint8_t type;
98 | /* Zone id. Please read VL53L5 user manual to find the zone id.Set macro
99 | * VL53L8CX_LAST_THRESHOLD to indicates the end of checkers */
100 | uint8_t zone_num;
101 | /* Mathematics operation (AND/OR). The first threshold is always OR.*/
102 | uint8_t mathematic_operation;
103 | } VL53L8CX_DetectionThresholds;
104 |
105 | /**
106 | * @brief This function allows indicating if the detection thresholds are
107 | * enabled.
108 | * @param (VL53L8CX_Configuration) *p_dev : VL53L8CX configuration structure.
109 | * @param (uint8_t) *p_enabled : Set to 1 if enabled, or 0 if disable.
110 | * @return (uint8_t) status : 0 if OK
111 | */
112 |
113 | uint8_t vl53l8cx_get_detection_thresholds_enable(
114 | VL53L8CX_Configuration *p_dev,
115 | uint8_t *p_enabled);
116 |
117 | /**
118 | * @brief This function allows enable the detection thresholds.
119 | * @param (VL53L8CX_Configuration) *p_dev : VL53L8CX configuration structure.
120 | * @param (uint8_t) enabled : Set to 1 to enable, or 0 to disable thresholds.
121 | * @return (uint8_t) status : 0 if programming is OK
122 | */
123 |
124 | uint8_t vl53l8cx_set_detection_thresholds_enable(
125 | VL53L8CX_Configuration *p_dev,
126 | uint8_t enabled);
127 |
128 | /**
129 | * @brief This function allows getting the detection thresholds.
130 | * @param (VL53L8CX_Configuration) *p_dev : VL53L8CX configuration structure.
131 | * @param (VL53L8CX_DetectionThresholds) *p_thresholds : Array of 64 thresholds.
132 | * @return (uint8_t) status : 0 if programming is OK
133 | */
134 |
135 | uint8_t vl53l8cx_get_detection_thresholds(
136 | VL53L8CX_Configuration *p_dev,
137 | VL53L8CX_DetectionThresholds *p_thresholds);
138 |
139 | /**
140 | * @brief This function allows programming the detection thresholds.
141 | * @param (VL53L8CX_Configuration) *p_dev : VL53L8CX configuration structure.
142 | * @param (VL53L8CX_DetectionThresholds) *p_thresholds : Array of 64 thresholds.
143 | * @return (uint8_t) status : 0 if programming is OK
144 | */
145 |
146 | uint8_t vl53l8cx_set_detection_thresholds(
147 | VL53L8CX_Configuration *p_dev,
148 | VL53L8CX_DetectionThresholds *p_thresholds);
149 |
150 | /**
151 | * @brief This function is used to enable or disable the auto-stop feature.
152 | * When ToF runs in autonomous mode with detection threshold, the sensor
153 | * only emits an interrupt (INT pin) when a threshold is reached. Interrupt
154 | * is raised when the measurement is completed. It is possible to abort the ranging
155 | * without waiting for end of measurement completed by enabling the auto-stop. The
156 | * sensor emits an interrupt and quickly aborts the measurements in progress. Please
157 | * note that vl53l8cx_stop_ranging() function needs to be used after interrupt raised
158 | * for a clean stop.
159 | * This function is used to get the auto_stop flag.
160 | * @param (VL53L8CX_Configuration) *p_dev : VL53L8CX configuration structure.
161 | * @param (uint8_t) *p_auto_stop : Pointer of auto-stop feature, 0 disabled
162 | * (default) or 1 enabled.
163 | * @return (uint8_t) status : 0 if programming is OK
164 | */
165 |
166 | uint8_t vl53l8cx_get_detection_thresholds_auto_stop(
167 | VL53L8CX_Configuration *p_dev,
168 | uint8_t *p_auto_stop);
169 |
170 | /**
171 | * @brief This function is used to enable or disable the auto-stop feature.
172 | * When ToF runs in autonomous mode with detection threshold, the sensor
173 | * only emits an interrupt (INT pin) when a threshold is reached. Interrupt
174 | * is raised when the measurement is completed. It is possible to abort the ranging
175 | * without waiting for end of measurement completed by enabling the auto-stop. The
176 | * sensor emits an interrupt and quickly aborts the measurements in progress. Please
177 | * note that vl53l8cx_stop_ranging() function needs to be used after interrupt raised
178 | * for a clean stop.
179 | * This function is used to set the auto_stop flag.
180 | * @param (VL53L8CX_Configuration) *p_dev : VL53L8CX configuration structure.
181 | * @param (uint8_t) *p_auto_stop : Pointer of auto-stop feature, 0 disabled
182 | * (default) or 1 enabled.
183 | * @return (uint8_t) status : 0 if programming is OK
184 | */
185 |
186 | uint8_t vl53l8cx_set_detection_thresholds_auto_stop(
187 | VL53L8CX_Configuration *p_dev,
188 | uint8_t auto_stop);
189 |
190 |
191 | #ifdef __cplusplus
192 | }
193 | #endif
194 |
195 | #endif /* VL53L8CX_PLUGIN_DETECTION_THRESHOLDS_H_ */
196 |
--------------------------------------------------------------------------------
/src/vl53l8cx_plugin_motion_indicator.c:
--------------------------------------------------------------------------------
1 | /**
2 | *
3 | * Copyright (c) 2021 STMicroelectronics.
4 | * All rights reserved.
5 | *
6 | * This software is licensed under terms that can be found in the LICENSE file
7 | * in the root directory of this software component.
8 | * If no LICENSE file comes with this software, it is provided AS-IS.
9 | *
10 | ******************************************************************************
11 | */
12 |
13 | #include
14 | #include "vl53l8cx_plugin_motion_indicator.h"
15 |
16 | uint8_t vl53l8cx_motion_indicator_init(
17 | VL53L8CX_Configuration *p_dev,
18 | VL53L8CX_Motion_Configuration *p_motion_config,
19 | uint8_t resolution)
20 | {
21 | uint8_t status = VL53L8CX_STATUS_OK;
22 |
23 | (void)memset(p_motion_config, 0, sizeof(VL53L8CX_Motion_Configuration));
24 |
25 | p_motion_config->ref_bin_offset = 13633;
26 | p_motion_config->detection_threshold = 2883584;
27 | p_motion_config->extra_noise_sigma = 0;
28 | p_motion_config->null_den_clip_value = 0;
29 | p_motion_config->mem_update_mode = 6;
30 | p_motion_config->mem_update_choice = 2;
31 | p_motion_config->sum_span = 4;
32 | p_motion_config->feature_length = 9;
33 | p_motion_config->nb_of_aggregates = 16;
34 | p_motion_config->nb_of_temporal_accumulations = 16;
35 | p_motion_config->min_nb_for_global_detection = 1;
36 | p_motion_config->global_indicator_format_1 = 8;
37 | p_motion_config->global_indicator_format_2 = 0;
38 | p_motion_config->spare_1 = 0;
39 | p_motion_config->spare_2 = 0;
40 | p_motion_config->spare_3 = 0;
41 |
42 | status |= vl53l8cx_motion_indicator_set_resolution(p_dev,
43 | p_motion_config, resolution);
44 |
45 | return status;
46 | }
47 |
48 | uint8_t vl53l8cx_motion_indicator_set_distance_motion(
49 | VL53L8CX_Configuration *p_dev,
50 | VL53L8CX_Motion_Configuration *p_motion_config,
51 | uint16_t distance_min_mm,
52 | uint16_t distance_max_mm)
53 | {
54 | uint8_t status = VL53L8CX_STATUS_OK;
55 | float_t tmp;
56 |
57 | if (((distance_max_mm - distance_min_mm) > (uint16_t)1500)
58 | || (distance_min_mm < (uint16_t)400)
59 | || (distance_max_mm > (uint16_t)4000)) {
60 | status |= VL53L8CX_STATUS_INVALID_PARAM;
61 | } else {
62 | tmp = (float_t)((((float_t)distance_min_mm / (float_t)37.5348)
63 | - (float_t)4.0) * (float_t)2048.5);
64 | p_motion_config->ref_bin_offset = (int32_t)tmp;
65 |
66 | tmp = (float_t)((((((float_t)distance_max_mm -
67 | (float_t)distance_min_mm) / (float_t)10.0) + (float_t)30.02784)
68 | / ((float_t)15.01392)) + (float_t)0.5);
69 | p_motion_config->feature_length = (uint8_t)tmp;
70 |
71 | status |= vl53l8cx_dci_write_data(p_dev,
72 | (uint8_t *)(p_motion_config),
73 | VL53L8CX_DCI_MOTION_DETECTOR_CFG,
74 | (uint16_t)sizeof(*p_motion_config));
75 | }
76 |
77 | return status;
78 | }
79 |
80 | uint8_t vl53l8cx_motion_indicator_set_resolution(
81 | VL53L8CX_Configuration *p_dev,
82 | VL53L8CX_Motion_Configuration *p_motion_config,
83 | uint8_t resolution)
84 | {
85 | uint8_t i, status = VL53L8CX_STATUS_OK;
86 |
87 | switch (resolution) {
88 | case VL53L8CX_RESOLUTION_4X4:
89 | for (i = 0; i < (uint8_t)VL53L8CX_RESOLUTION_4X4; i++) {
90 | p_motion_config->map_id[i] = (int8_t)i;
91 | }
92 | (void)memset(p_motion_config->map_id + 16, -1, 48);
93 | break;
94 |
95 | case VL53L8CX_RESOLUTION_8X8:
96 | for (i = 0; i < (uint8_t)VL53L8CX_RESOLUTION_8X8; i++) {
97 | p_motion_config->map_id[i] = (int8_t)((((int8_t)
98 | i % 8) / 2) + (4 * ((int8_t)i / 16)));
99 | }
100 | break;
101 |
102 | default:
103 | status |= VL53L8CX_STATUS_ERROR;
104 | break;
105 | }
106 |
107 | if (status == VL53L8CX_STATUS_OK) {
108 | status |= vl53l8cx_dci_write_data(p_dev,
109 | (uint8_t *)(p_motion_config),
110 | VL53L8CX_DCI_MOTION_DETECTOR_CFG,
111 | (uint16_t)sizeof(*p_motion_config));
112 | }
113 |
114 | return status;
115 | }
116 |
--------------------------------------------------------------------------------
/src/vl53l8cx_plugin_motion_indicator.h:
--------------------------------------------------------------------------------
1 | /**
2 | *
3 | * Copyright (c) 2021 STMicroelectronics.
4 | * All rights reserved.
5 | *
6 | * This software is licensed under terms that can be found in the LICENSE file
7 | * in the root directory of this software component.
8 | * If no LICENSE file comes with this software, it is provided AS-IS.
9 | *
10 | ******************************************************************************
11 | */
12 |
13 | #ifndef VL53L8CX_PLUGIN_MOTION_INDICATOR_H_
14 | #define VL53L8CX_PLUGIN_MOTION_INDICATOR_H_
15 |
16 | #ifdef __cplusplus
17 | extern "C" {
18 | #endif
19 |
20 | #include "vl53l8cx_api.h"
21 |
22 | /**
23 | * @brief Motion indicator internal configuration structure.
24 | */
25 |
26 | typedef struct {
27 | int32_t ref_bin_offset;
28 | uint32_t detection_threshold;
29 | uint32_t extra_noise_sigma;
30 | uint32_t null_den_clip_value;
31 | uint8_t mem_update_mode;
32 | uint8_t mem_update_choice;
33 | uint8_t sum_span;
34 | uint8_t feature_length;
35 | uint8_t nb_of_aggregates;
36 | uint8_t nb_of_temporal_accumulations;
37 | uint8_t min_nb_for_global_detection;
38 | uint8_t global_indicator_format_1;
39 | uint8_t global_indicator_format_2;
40 | uint8_t spare_1;
41 | uint8_t spare_2;
42 | uint8_t spare_3;
43 | int8_t map_id[64];
44 | uint8_t indicator_format_1[32];
45 | uint8_t indicator_format_2[32];
46 | } VL53L8CX_Motion_Configuration;
47 |
48 | /**
49 | * @brief This function is used to initialized the motion indicator. By default,
50 | * indicator is programmed to monitor movements between 400mm and 1500mm.
51 | * @param (VL53L8CX_Configuration) *p_dev : VL53L8CX configuration structure.
52 | * @param (VL53L8CX_Motion_Configuration) *p_motion_config : Structure
53 | * containing the initialized motion configuration.
54 | * @param (uint8_t) resolution : Wanted resolution, defined by macros
55 | * VL53L8CX_RESOLUTION_4X4 or VL53L8CX_RESOLUTION_8X8.
56 | * @return (uint8_t) status : 0 if OK, or 127 is the resolution is unknown.
57 | */
58 |
59 | uint8_t vl53l8cx_motion_indicator_init(
60 | VL53L8CX_Configuration *p_dev,
61 | VL53L8CX_Motion_Configuration *p_motion_config,
62 | uint8_t resolution);
63 |
64 | /**
65 | * @brief This function can be used to change the working distance of motion
66 | * indicator. By default, indicator is programmed to monitor movements between
67 | * 400mm and 1500mm.
68 | * @param (VL53L8CX_Configuration) *p_dev : VL53L8CX configuration structure.
69 | * @param (VL53L8CX_Motion_Configuration) *p_motion_config : Structure
70 | * containing the initialized motion configuration.
71 | * @param (uint16_t) distance_min_mm : Minimum distance for indicator (min value
72 | * 400mm, max 4000mm).
73 | * @param (uint16_t) distance_max_mm : Maximum distance for indicator (min value
74 | * 400mm, max 4000mm).
75 | * VL53L8CX_RESOLUTION_4X4 or VL53L8CX_RESOLUTION_8X8.
76 | * @return (uint8_t) status : 0 if OK, or 127 if an argument is invalid.
77 | */
78 |
79 | uint8_t vl53l8cx_motion_indicator_set_distance_motion(
80 | VL53L8CX_Configuration *p_dev,
81 | VL53L8CX_Motion_Configuration *p_motion_config,
82 | uint16_t distance_min_mm,
83 | uint16_t distance_max_mm);
84 |
85 | /**
86 | * @brief This function is used to update the internal motion indicator map.
87 | * @param (VL53L8CX_Configuration) *p_dev : VL53L8CX configuration structure.
88 | * @param (VL53L8CX_Motion_Configuration) *p_motion_config : Structure
89 | * containing the initialized motion configuration.
90 | * @param (uint8_t) resolution : Wanted SCI resolution, defined by macros
91 | * VL53L8CX_RESOLUTION_4X4 or VL53L8CX_RESOLUTION_8X8.
92 | * @return (uint8_t) status : 0 if OK, or 127 is the resolution is unknown.
93 | */
94 |
95 | uint8_t vl53l8cx_motion_indicator_set_resolution(
96 | VL53L8CX_Configuration *p_dev,
97 | VL53L8CX_Motion_Configuration *p_motion_config,
98 | uint8_t resolution);
99 |
100 | #ifdef __cplusplus
101 | }
102 | #endif
103 |
104 | #endif /* VL53L8CX_PLUGIN_MOTION_INDICATOR_H_ */
105 |
--------------------------------------------------------------------------------
/src/vl53l8cx_plugin_xtalk.c:
--------------------------------------------------------------------------------
1 | /**
2 | *
3 | * Copyright (c) 2021 STMicroelectronics.
4 | * All rights reserved.
5 | *
6 | * This software is licensed under terms that can be found in the LICENSE file
7 | * in the root directory of this software component.
8 | * If no LICENSE file comes with this software, it is provided AS-IS.
9 | *
10 | ******************************************************************************
11 | */
12 |
13 | #include "vl53l8cx_plugin_xtalk.h"
14 |
15 | /*
16 | * Inner function, not available outside this file. This function is used to
17 | * wait for an answer from VL53L5 sensor.
18 | */
19 |
20 | static uint8_t _vl53l8cx_poll_for_answer(
21 | VL53L8CX_Configuration *p_dev,
22 | uint16_t address,
23 | uint8_t expected_value)
24 | {
25 | uint8_t status = VL53L8CX_STATUS_OK;
26 | uint8_t timeout = 0;
27 |
28 | do {
29 | status |= VL53L8CX_RdMulti(&(p_dev->platform),
30 | address, p_dev->temp_buffer, 4);
31 | status |= VL53L8CX_WaitMs(&(p_dev->platform), 10);
32 |
33 | /* 2s timeout or FW error*/
34 | if ((timeout >= (uint8_t)200)
35 | || (p_dev->temp_buffer[2] >= (uint8_t) 0x7f)) {
36 | status |= VL53L8CX_MCU_ERROR;
37 | break;
38 | } else {
39 | timeout++;
40 | }
41 | } while ((p_dev->temp_buffer[0x1]) != expected_value);
42 |
43 | return status;
44 | }
45 |
46 | /*
47 | * Inner function, not available outside this file. This function is used to
48 | * program the output using the macro defined into the 'vl53l8cx_platform.h' file.
49 | */
50 |
51 | static uint8_t _vl53l8cx_program_output_config(
52 | VL53L8CX_Configuration *p_dev)
53 | {
54 | uint8_t resolution, status = VL53L8CX_STATUS_OK;
55 | uint32_t i;
56 | uint32_t header_config[2] = {0, 0};
57 | union Block_header *bh_ptr;
58 |
59 | status |= vl53l8cx_get_resolution(p_dev, &resolution);
60 | p_dev->data_read_size = 0;
61 |
62 | /* Enable mandatory output (meta and common data) */
63 | uint32_t output_bh_enable[] = {
64 | 0x0001FFFFU,
65 | 0x00000000U,
66 | 0x00000000U,
67 | 0xC0000000U
68 | };
69 |
70 | /* Send addresses of possible output */
71 | uint32_t output[] = {
72 | 0x0000000DU,
73 | 0x54000040U,
74 | 0x9FD800C0U,
75 | 0x9FE40140U,
76 | 0x9FF80040U,
77 | 0x9FFC0404U,
78 | 0xA0FC0100U,
79 | 0xA10C0100U,
80 | 0xA11C00C0U,
81 | 0xA1280902U,
82 | 0xA2480040U,
83 | 0xA24C0081U,
84 | 0xA2540081U,
85 | 0xA25C0081U,
86 | 0xA2640081U,
87 | 0xA26C0084U,
88 | 0xA28C0082U
89 | };
90 |
91 | /* Update data size */
92 | for (i = 0; i < (uint32_t)(sizeof(output) / sizeof(uint32_t)); i++) {
93 | if ((output[i] == (uint8_t)0)
94 | || ((output_bh_enable[i / (uint32_t)32]
95 | & ((uint32_t)1 << (i % (uint32_t)32))) == (uint32_t)0)) {
96 | continue;
97 | }
98 |
99 | bh_ptr = (union Block_header *) & (output[i]);
100 | if (((uint8_t)bh_ptr->type >= (uint8_t)0x1)
101 | && ((uint8_t)bh_ptr->type < (uint8_t)0x0d)) {
102 | if ((bh_ptr->idx >= (uint16_t)0x54d0)
103 | && (bh_ptr->idx < (uint16_t)(0x54d0 + 960))) {
104 | bh_ptr->size = resolution;
105 | } else {
106 | bh_ptr->size = (uint8_t)(resolution
107 | * (uint8_t)VL53L8CX_NB_TARGET_PER_ZONE);
108 | }
109 |
110 |
111 | p_dev->data_read_size += bh_ptr->type * bh_ptr->size;
112 | } else {
113 | p_dev->data_read_size += bh_ptr->size;
114 | }
115 |
116 | p_dev->data_read_size += (uint32_t)4;
117 | }
118 | p_dev->data_read_size += (uint32_t)24;
119 |
120 | status |= vl53l8cx_dci_write_data(p_dev,
121 | (uint8_t *) & (output),
122 | VL53L8CX_DCI_OUTPUT_LIST, (uint16_t)sizeof(output));
123 |
124 | header_config[0] = p_dev->data_read_size;
125 | header_config[1] = i + (uint32_t)1;
126 |
127 | status |= vl53l8cx_dci_write_data(p_dev, (uint8_t *) & (header_config),
128 | VL53L8CX_DCI_OUTPUT_CONFIG,
129 | (uint16_t)sizeof(header_config));
130 | status |= vl53l8cx_dci_write_data(p_dev, (uint8_t *) & (output_bh_enable),
131 | VL53L8CX_DCI_OUTPUT_ENABLES,
132 | (uint16_t)sizeof(output_bh_enable));
133 |
134 | return status;
135 | }
136 |
137 | uint8_t vl53l8cx_calibrate_xtalk(
138 | VL53L8CX_Configuration *p_dev,
139 | uint16_t reflectance_percent,
140 | uint8_t nb_samples,
141 | uint16_t distance_mm)
142 | {
143 | uint16_t timeout = 0;
144 | uint8_t cmd[] = {0x00, 0x03, 0x00, 0x00};
145 | uint8_t footer[] = {0x00, 0x00, 0x00, 0x0F, 0x00, 0x01, 0x03, 0x04};
146 | uint8_t continue_loop = 1, status = VL53L8CX_STATUS_OK;
147 |
148 | uint8_t resolution, frequency, target_order, sharp_prct, ranging_mode;
149 | uint32_t integration_time_ms, xtalk_margin;
150 |
151 | uint16_t reflectance = reflectance_percent;
152 | uint8_t samples = nb_samples;
153 | uint16_t distance = distance_mm;
154 | uint8_t *default_xtalk_ptr;
155 |
156 | /* Get initial configuration */
157 | status |= vl53l8cx_get_resolution(p_dev, &resolution);
158 | status |= vl53l8cx_get_ranging_frequency_hz(p_dev, &frequency);
159 | status |= vl53l8cx_get_integration_time_ms(p_dev, &integration_time_ms);
160 | status |= vl53l8cx_get_sharpener_percent(p_dev, &sharp_prct);
161 | status |= vl53l8cx_get_target_order(p_dev, &target_order);
162 | status |= vl53l8cx_get_xtalk_margin(p_dev, &xtalk_margin);
163 | status |= vl53l8cx_get_ranging_mode(p_dev, &ranging_mode);
164 |
165 | /* Check input arguments validity */
166 | if (((reflectance < (uint16_t)1) || (reflectance > (uint16_t)99))
167 | || ((distance < (uint16_t)600) || (distance > (uint16_t)3000))
168 | || ((samples < (uint8_t)1) || (samples > (uint8_t)16))) {
169 | status |= VL53L8CX_STATUS_INVALID_PARAM;
170 | } else {
171 | status |= vl53l8cx_set_resolution(p_dev,
172 | VL53L8CX_RESOLUTION_8X8);
173 |
174 | /* Send Xtalk calibration buffer */
175 | (void)memcpy(p_dev->temp_buffer, VL53L8CX_CALIBRATE_XTALK,
176 | sizeof(VL53L8CX_CALIBRATE_XTALK));
177 | status |= VL53L8CX_WrMulti(&(p_dev->platform), 0x2c28,
178 | p_dev->temp_buffer,
179 | (uint16_t)sizeof(VL53L8CX_CALIBRATE_XTALK));
180 | status |= _vl53l8cx_poll_for_answer(p_dev,
181 | VL53L8CX_UI_CMD_STATUS, 0x3);
182 |
183 | /* Format input argument */
184 | reflectance = reflectance * (uint16_t)16;
185 | distance = distance * (uint16_t)4;
186 |
187 | /* Update required fields */
188 | status |= vl53l8cx_dci_replace_data(p_dev, p_dev->temp_buffer,
189 | VL53L8CX_DCI_CAL_CFG, 8,
190 | (uint8_t *)&distance, 2, 0x00);
191 |
192 | status |= vl53l8cx_dci_replace_data(p_dev, p_dev->temp_buffer,
193 | VL53L8CX_DCI_CAL_CFG, 8,
194 | (uint8_t *)&reflectance, 2, 0x02);
195 |
196 | status |= vl53l8cx_dci_replace_data(p_dev, p_dev->temp_buffer,
197 | VL53L8CX_DCI_CAL_CFG, 8,
198 | (uint8_t *)&samples, 1, 0x04);
199 |
200 | /* Program output for Xtalk calibration */
201 | status |= _vl53l8cx_program_output_config(p_dev);
202 |
203 | /* Start ranging session */
204 | status |= VL53L8CX_WrMulti(&(p_dev->platform),
205 | VL53L8CX_UI_CMD_END - (uint16_t)(4 - 1),
206 | (uint8_t *)cmd, sizeof(cmd));
207 | status |= _vl53l8cx_poll_for_answer(p_dev,
208 | VL53L8CX_UI_CMD_STATUS, 0x3);
209 |
210 | /* Wait for end of calibration */
211 | do {
212 | status |= VL53L8CX_RdMulti(&(p_dev->platform),
213 | 0x0, p_dev->temp_buffer, 4);
214 | if (p_dev->temp_buffer[0] != VL53L8CX_STATUS_ERROR) {
215 | /* Coverglass too good for Xtalk calibration */
216 | if ((p_dev->temp_buffer[2] >= (uint8_t)0x7f) &&
217 | (((uint16_t)(p_dev->temp_buffer[3] &
218 | (uint16_t)0x80) >> 7) == (uint16_t)1)) {
219 | default_xtalk_ptr = p_dev->default_xtalk;
220 | (void)memcpy(p_dev->xtalk_data,
221 | default_xtalk_ptr,
222 | sizeof(p_dev->xtalk_data));
223 | status |= VL53L8CX_STATUS_XTALK_FAILED;
224 | }
225 | continue_loop = (uint8_t)0;
226 | } else if (timeout >= (uint16_t)400) {
227 | status |= VL53L8CX_STATUS_ERROR;
228 | continue_loop = (uint8_t)0;
229 | } else {
230 | timeout++;
231 | status |= VL53L8CX_WaitMs(&(p_dev->platform), 50);
232 | }
233 |
234 | } while (continue_loop == (uint8_t)1);
235 | }
236 |
237 | /* Save Xtalk data into the Xtalk buffer */
238 | (void)memcpy(p_dev->temp_buffer, VL53L8CX_GET_XTALK_CMD,
239 | sizeof(VL53L8CX_GET_XTALK_CMD));
240 | status |= VL53L8CX_WrMulti(&(p_dev->platform), 0x2fb8,
241 | p_dev->temp_buffer,
242 | (uint16_t)sizeof(VL53L8CX_GET_XTALK_CMD));
243 | status |= _vl53l8cx_poll_for_answer(p_dev, VL53L8CX_UI_CMD_STATUS, 0x03);
244 | status |= VL53L8CX_RdMulti(&(p_dev->platform), VL53L8CX_UI_CMD_START,
245 | p_dev->temp_buffer,
246 | VL53L8CX_XTALK_BUFFER_SIZE + (uint16_t)4);
247 |
248 | (void)memcpy(&(p_dev->xtalk_data[0]), &(p_dev->temp_buffer[8]),
249 | VL53L8CX_XTALK_BUFFER_SIZE - (uint16_t)8);
250 | (void)memcpy(&(p_dev->xtalk_data[VL53L8CX_XTALK_BUFFER_SIZE
251 | - (uint16_t)8]), footer, sizeof(footer));
252 |
253 | /* Reset default buffer */
254 | status |= VL53L8CX_WrMulti(&(p_dev->platform), 0x2c34,
255 | p_dev->default_configuration,
256 | VL53L8CX_CONFIGURATION_SIZE);
257 | status |= _vl53l8cx_poll_for_answer(p_dev, VL53L8CX_UI_CMD_STATUS, 0x03);
258 |
259 | /* Reset initial configuration */
260 | status |= vl53l8cx_set_resolution(p_dev, resolution);
261 | status |= vl53l8cx_set_ranging_frequency_hz(p_dev, frequency);
262 | status |= vl53l8cx_set_integration_time_ms(p_dev, integration_time_ms);
263 | status |= vl53l8cx_set_sharpener_percent(p_dev, sharp_prct);
264 | status |= vl53l8cx_set_target_order(p_dev, target_order);
265 | status |= vl53l8cx_set_xtalk_margin(p_dev, xtalk_margin);
266 | status |= vl53l8cx_set_ranging_mode(p_dev, ranging_mode);
267 |
268 | return status;
269 | }
270 |
271 | uint8_t vl53l8cx_get_caldata_xtalk(
272 | VL53L8CX_Configuration *p_dev,
273 | uint8_t *p_xtalk_data)
274 | {
275 | uint8_t status = VL53L8CX_STATUS_OK, resolution;
276 | uint8_t footer[] = {0x00, 0x00, 0x00, 0x0F, 0x00, 0x01, 0x03, 0x04};
277 |
278 | status |= vl53l8cx_get_resolution(p_dev, &resolution);
279 | status |= vl53l8cx_set_resolution(p_dev, VL53L8CX_RESOLUTION_8X8);
280 |
281 | (void)memcpy(p_dev->temp_buffer, VL53L8CX_GET_XTALK_CMD,
282 | sizeof(VL53L8CX_GET_XTALK_CMD));
283 | status |= VL53L8CX_WrMulti(&(p_dev->platform), 0x2fb8,
284 | p_dev->temp_buffer, sizeof(VL53L8CX_GET_XTALK_CMD));
285 | status |= _vl53l8cx_poll_for_answer(p_dev, VL53L8CX_UI_CMD_STATUS, 0x03);
286 | status |= VL53L8CX_RdMulti(&(p_dev->platform), VL53L8CX_UI_CMD_START,
287 | p_dev->temp_buffer,
288 | VL53L8CX_XTALK_BUFFER_SIZE + (uint16_t)4);
289 |
290 | (void)memcpy(&(p_xtalk_data[0]), &(p_dev->temp_buffer[8]),
291 | VL53L8CX_XTALK_BUFFER_SIZE - (uint16_t)8);
292 | (void)memcpy(&(p_xtalk_data[VL53L8CX_XTALK_BUFFER_SIZE - (uint16_t)8]),
293 | footer, sizeof(footer));
294 |
295 | status |= vl53l8cx_set_resolution(p_dev, resolution);
296 |
297 | return status;
298 | }
299 |
300 | uint8_t vl53l8cx_set_caldata_xtalk(
301 | VL53L8CX_Configuration *p_dev,
302 | uint8_t *p_xtalk_data)
303 | {
304 | uint8_t resolution, status = VL53L8CX_STATUS_OK;
305 |
306 | status |= vl53l8cx_get_resolution(p_dev, &resolution);
307 | (void)memcpy(p_dev->xtalk_data, p_xtalk_data, VL53L8CX_XTALK_BUFFER_SIZE);
308 | status |= vl53l8cx_set_resolution(p_dev, resolution);
309 |
310 | return status;
311 | }
312 |
313 | uint8_t vl53l8cx_get_xtalk_margin(
314 | VL53L8CX_Configuration *p_dev,
315 | uint32_t *p_xtalk_margin)
316 | {
317 | uint8_t status = VL53L8CX_STATUS_OK;
318 |
319 | status |= vl53l8cx_dci_read_data(p_dev, (uint8_t *)p_dev->temp_buffer,
320 | VL53L8CX_DCI_XTALK_CFG, 16);
321 |
322 | (void)memcpy(p_xtalk_margin, p_dev->temp_buffer, 4);
323 | *p_xtalk_margin = *p_xtalk_margin / (uint32_t)2048;
324 |
325 | return status;
326 | }
327 |
328 | uint8_t vl53l8cx_set_xtalk_margin(
329 | VL53L8CX_Configuration *p_dev,
330 | uint32_t xtalk_margin)
331 | {
332 | uint8_t status = VL53L8CX_STATUS_OK;
333 | uint32_t margin_kcps = xtalk_margin;
334 |
335 | if (margin_kcps > (uint32_t)10000) {
336 | status |= VL53L8CX_STATUS_INVALID_PARAM;
337 | } else {
338 | margin_kcps = margin_kcps * (uint32_t)2048;
339 | status |= vl53l8cx_dci_replace_data(p_dev, p_dev->temp_buffer,
340 | VL53L8CX_DCI_XTALK_CFG, 16,
341 | (uint8_t *)&margin_kcps, 4, 0x00);
342 | }
343 |
344 | return status;
345 | }
346 |
--------------------------------------------------------------------------------
/src/vl53l8cx_plugin_xtalk.h:
--------------------------------------------------------------------------------
1 | /**
2 | *
3 | * Copyright (c) 2021 STMicroelectronics.
4 | * All rights reserved.
5 | *
6 | * This software is licensed under terms that can be found in the LICENSE file
7 | * in the root directory of this software component.
8 | * If no LICENSE file comes with this software, it is provided AS-IS.
9 | *
10 | ******************************************************************************
11 | */
12 |
13 | #ifndef VL53L8CX_PLUGIN_XTALK_H_
14 | #define VL53L8CX_PLUGIN_XTALK_H_
15 |
16 | #ifdef __cplusplus
17 | extern "C" {
18 | #endif
19 |
20 |
21 | #include "vl53l8cx_api.h"
22 |
23 | /**
24 | * @brief Inner internal number of targets.
25 | */
26 |
27 | #if VL53L8CX_NB_TARGET_PER_ZONE == 1
28 | #define VL53L8CX_FW_NBTAR_XTALK 2
29 | #else
30 | #define VL53L8CX_FW_NBTAR_XTALK VL53L8CX_NB_TARGET_PER_ZONE
31 | #endif
32 |
33 | /**
34 | * @brief Inner Macro for plugin. Not for user, only for development.
35 | */
36 |
37 | #define VL53L8CX_DCI_CAL_CFG ((uint16_t)0x5470U)
38 | #define VL53L8CX_DCI_XTALK_CFG ((uint16_t)0xAD94U)
39 |
40 |
41 | /**
42 | * @brief This function starts the VL53L8CX sensor in order to calibrate Xtalk.
43 | * This calibration is recommended is user wants to use a coverglass.
44 | * @param (VL53L8CX_Configuration) *p_dev : VL53L8CX configuration structure.
45 | * @param (uint16_t) reflectance_percent : Target reflectance in percent. This
46 | * value is include between 1 and 99%. For a better efficiency, ST recommends a
47 | * 3% target reflectance.
48 | * @param (uint8_t) nb_samples : Nb of samples used for calibration. A higher
49 | * number of samples means a higher accuracy, but it increases the calibration
50 | * time. Minimum is 1 and maximum is 16.
51 | * @param (uint16_t) distance_mm : Target distance in mm. The minimum allowed
52 | * distance is 600mm, and maximum is 3000mm. The target must stay in Full FOV,
53 | * so short distance are easier for calibration.
54 | * @return (uint8_t) status : 0 if calibration OK, 127 if an argument has an
55 | * incorrect value, or 255 is something failed.
56 | */
57 |
58 | uint8_t vl53l8cx_calibrate_xtalk(
59 | VL53L8CX_Configuration *p_dev,
60 | uint16_t reflectance_percent,
61 | uint8_t nb_samples,
62 | uint16_t distance_mm);
63 |
64 | /**
65 | * @brief This function gets the Xtalk buffer. The buffer is available after
66 | * using the function vl53l8cx_calibrate_xtalk().
67 | * @param (VL53L8CX_Configuration) *p_dev : VL53L5 configuration structure.
68 | * @param (uint8_t) *p_xtalk_data : Buffer with a size defined by
69 | * macro VL53L8CX_XTALK_SIZE.
70 | * @return (uint8_t) status : 0 if buffer reading OK
71 | */
72 |
73 | uint8_t vl53l8cx_get_caldata_xtalk(
74 | VL53L8CX_Configuration *p_dev,
75 | uint8_t *p_xtalk_data);
76 |
77 | /**
78 | * @brief This function sets the Xtalk buffer. This function can be used to
79 | * override default Xtalk buffer.
80 | * @param (VL53L8CX_Configuration) *p_dev : VL53L5 configuration structure.
81 | * @param (uint8_t) *p_xtalk_data : Buffer with a size defined by
82 | * macro VL53L8CX_XTALK_SIZE.
83 | * @return (uint8_t) status : 0 if buffer OK
84 | */
85 |
86 | uint8_t vl53l8cx_set_caldata_xtalk(
87 | VL53L8CX_Configuration *p_dev,
88 | uint8_t *p_xtalk_data);
89 |
90 | /**
91 | * @brief This function gets the Xtalk margin. This margin is used to increase
92 | * the Xtalk threshold. It can also be used to avoid false positives after the
93 | * Xtalk calibration. The default value is 50 kcps/spads.
94 | * @param (VL53L8CX_Configuration) *p_dev : VL53L8CX configuration structure.
95 | * @param (uint32_t) *p_xtalk_margin : Xtalk margin in kcps/spads.
96 | * @return (uint8_t) status : 0 if reading OK
97 | */
98 |
99 | uint8_t vl53l8cx_get_xtalk_margin(
100 | VL53L8CX_Configuration *p_dev,
101 | uint32_t *p_xtalk_margin);
102 |
103 | /**
104 | * @brief This function sets the Xtalk margin. This margin is used to increase
105 | * the Xtalk threshold. It can also be used to avoid false positives after the
106 | * Xtalk calibration. The default value is 50 kcps/spads.
107 | * @param (VL53L8CX_Configuration) *p_dev : VL53L8CX configuration structure.
108 | * @param (uint32_t) xtalk_margin : New Xtalk margin in kcps/spads. Min value is
109 | * 0 kcps/spads, and max is 10.000 kcps/spads
110 | * @return (uint8_t) status : 0 if set margin is OK, or 127 is the margin is
111 | * invalid.
112 | */
113 |
114 | uint8_t vl53l8cx_set_xtalk_margin(
115 | VL53L8CX_Configuration *p_dev,
116 | uint32_t xtalk_margin);
117 |
118 | /**
119 | * @brief Command used to get Xtalk calibration data
120 | */
121 |
122 | static const uint8_t VL53L8CX_GET_XTALK_CMD[] = {
123 | 0x54, 0x00, 0x00, 0x40,
124 | 0x9F, 0xD8, 0x00, 0xC0,
125 | 0x9F, 0xE4, 0x01, 0x40,
126 | 0x9F, 0xF8, 0x00, 0x40,
127 | 0x9F, 0xFC, 0x04, 0x04,
128 | 0xA0, 0xFC, 0x01, 0x00,
129 | 0xA1, 0x0C, 0x01, 0x00,
130 | 0xA1, 0x1C, 0x00, 0xC0,
131 | 0xA1, 0x28, 0x09, 0x02,
132 | 0xA2, 0x48, 0x00, 0x40,
133 | 0xA2, 0x4C, 0x00, 0x81,
134 | 0xA2, 0x54, 0x00, 0x81,
135 | 0xA2, 0x5C, 0x00, 0x81,
136 | 0xA2, 0x64, 0x00, 0x81,
137 | 0xA2, 0x6C, 0x00, 0x84,
138 | 0xA2, 0x8C, 0x00, 0x82,
139 | 0x00, 0x00, 0x00, 0x0F,
140 | 0x07, 0x02, 0x00, 0x44
141 | };
142 |
143 | /**
144 | * @brief Command used to get run Xtalk calibration
145 | */
146 |
147 | static const uint8_t VL53L8CX_CALIBRATE_XTALK[] = {
148 | 0x54, 0x50, 0x00, 0x80,
149 | 0x00, 0x04, 0x08, 0x08,
150 | 0x00, 0x00, 0x04, 0x04,
151 | 0xAD, 0x30, 0x00, 0x80,
152 | 0x03, 0x01, 0x06, 0x03,
153 | 0x00, 0x00, 0x01, 0x00,
154 | 0xAD, 0x38, 0x01, 0x00,
155 | 0x01, 0xE0, 0x01, 0x40,
156 | 0x00, 0x10, 0x00, 0x10,
157 | 0x01, 0x00, 0x01, 0x00,
158 | 0x00, 0x00, 0x00, 0x01,
159 | 0x54, 0x58, 0x00, 0x40,
160 | 0x04, 0x1A, 0x02, 0x00,
161 | 0x54, 0x5C, 0x01, 0x40,
162 | 0x00, 0x01, 0x00, 0x51,
163 | 0x00, 0x00, 0x0F, 0xA0,
164 | 0x0F, 0xA0, 0x03, 0xE8,
165 | 0x02, 0x80, 0x1F, 0x40,
166 | 0x00, 0x00, 0x05, 0x00,
167 | 0x54, 0x70, 0x00, 0x80,
168 | 0x03, 0x20, 0x03, 0x20,
169 | 0x00, 0x00, 0x00, 0x08,
170 | 0x54, 0x78, 0x01, 0x00,
171 | 0x01, 0x1B, 0x00, 0x21,
172 | 0x00, 0x33, 0x00, 0x00,
173 | 0x02, 0x00, 0x00, 0x01,
174 | 0x04, 0x01, 0x08, VL53L8CX_FW_NBTAR_XTALK,
175 | 0x54, 0x88, 0x01, 0x40,
176 | 0x00, 0x00, 0x00, 0x00,
177 | 0x00, 0x00, 0x00, 0x00,
178 | 0x00, 0x00, 0x00, 0x00,
179 | 0x00, 0x00, 0x00, 0x00,
180 | 0x00, 0x00, 0x08, 0x00,
181 | 0xAD, 0x48, 0x01, 0x00,
182 | 0x01, 0xF4, 0x00, 0x00,
183 | 0x03, 0x06, 0x00, 0x10,
184 | 0x08, 0x08, 0x08, 0x08,
185 | 0x00, 0x00, 0x00, 0x08,
186 | 0xAD, 0x60, 0x01, 0x00,
187 | 0x00, 0x00, 0x00, 0x80,
188 | 0x00, 0x00, 0x00, 0x00,
189 | 0x20, 0x1F, 0x01, 0xF4,
190 | 0x00, 0x00, 0x1D, 0x0A,
191 | 0xAD, 0x70, 0x00, 0x80,
192 | 0x08, 0x00, 0x1F, 0x40,
193 | 0x00, 0x00, 0x00, 0x01,
194 | 0xAD, 0x78, 0x00, 0x80,
195 | 0x00, 0xA0, 0x03, 0x20,
196 | 0x00, 0x01, 0x01, 0x90,
197 | 0xAD, 0x80, 0x00, 0x40,
198 | 0x00, 0x00, 0x28, 0x00,
199 | 0xAD, 0x84, 0x00, 0x80,
200 | 0x00, 0x00, 0x32, 0x00,
201 | 0x03, 0x20, 0x00, 0x00,
202 | 0xAD, 0x8C, 0x00, 0x80,
203 | 0x02, 0x58, 0xFF, 0x38,
204 | 0x00, 0x00, 0x00, 0x0C,
205 | 0xAD, 0x94, 0x01, 0x00,
206 | 0x00, 0x01, 0x90, 0x00,
207 | 0xFF, 0xFF, 0xFC, 0x00,
208 | 0x00, 0x00, 0x04, 0x00,
209 | 0x00, 0x00, 0x01, 0x00,
210 | 0xAD, 0xA4, 0x00, 0xC0,
211 | 0x04, 0x80, 0x06, 0x1A,
212 | 0x00, 0x80, 0x05, 0x80,
213 | 0x00, 0x00, 0x01, 0x06,
214 | 0xAD, 0xB0, 0x00, 0xC0,
215 | 0x04, 0x80, 0x06, 0x1A,
216 | 0x19, 0x00, 0x05, 0x80,
217 | 0x00, 0x00, 0x01, 0x90,
218 | 0xAD, 0xBC, 0x04, 0x40,
219 | 0x00, 0x00, 0x00, 0x00,
220 | 0x00, 0x00, 0x00, 0x00,
221 | 0x00, 0x12, 0x00, 0x25,
222 | 0x00, 0x00, 0x00, 0x06,
223 | 0x00, 0x00, 0x00, 0x05,
224 | 0x00, 0x00, 0x00, 0x05,
225 | 0x00, 0x00, 0x00, 0x06,
226 | 0x00, 0x00, 0x00, 0x04,
227 | 0x00, 0x00, 0x00, 0x0F,
228 | 0x00, 0x00, 0x00, 0x5A,
229 | 0x00, 0x00, 0x00, 0x00,
230 | 0x00, 0x00, 0x00, 0x09,
231 | 0x0B, 0x0C, 0x0B, 0x0B,
232 | 0x03, 0x03, 0x11, 0x05,
233 | 0x01, 0x01, 0x01, 0x01,
234 | 0x00, 0x00, 0x00, 0x00,
235 | 0x00, 0x0D, 0x00, 0x00,
236 | 0xAE, 0x00, 0x01, 0x04,
237 | 0x00, 0x00, 0x00, 0x04,
238 | 0x00, 0x00, 0x00, 0x08,
239 | 0x00, 0x00, 0x00, 0x0A,
240 | 0x00, 0x00, 0x00, 0x0C,
241 | 0x00, 0x00, 0x00, 0x0D,
242 | 0x00, 0x00, 0x00, 0x0E,
243 | 0x00, 0x00, 0x00, 0x08,
244 | 0x00, 0x00, 0x00, 0x08,
245 | 0x00, 0x00, 0x00, 0x10,
246 | 0x00, 0x00, 0x00, 0x10,
247 | 0x00, 0x00, 0x00, 0x20,
248 | 0x00, 0x00, 0x00, 0x20,
249 | 0x00, 0x00, 0x00, 0x06,
250 | 0x00, 0x00, 0x05, 0x0A,
251 | 0x02, 0x00, 0x0C, 0x08,
252 | 0x00, 0x00, 0x00, 0x00,
253 | 0xAE, 0x40, 0x00, 0x40,
254 | 0x00, 0x00, 0x00, 0xFF,
255 | 0xAE, 0x44, 0x00, 0x40,
256 | 0x00, 0x10, 0x04, 0x01,
257 | 0xAE, 0x48, 0x00, 0x40,
258 | 0x00, 0x00, 0x10, 0x00,
259 | 0xAE, 0x4C, 0x00, 0x40,
260 | 0x00, 0x00, 0x00, 0x01,
261 | 0xAE, 0x50, 0x01, 0x40,
262 | 0x00, 0x00, 0x00, 0x14,
263 | 0x04, 0x00, 0x28, 0x00,
264 | 0x03, 0x20, 0x6C, 0x00,
265 | 0x00, 0x00, 0x00, 0x00,
266 | 0x00, 0x00, 0x00, 0x00,
267 | 0xAE, 0x64, 0x00, 0x40,
268 | 0x00, 0x00, 0x00, 0x01,
269 | 0xAE, 0xD8, 0x01, 0x00,
270 | 0x00, 0xC8, 0x05, 0xDC,
271 | 0x00, 0x00, 0x0C, 0xCD,
272 | 0x01, 0x04, 0x00, 0x00,
273 | 0x00, 0x01, 0x26, 0x01,
274 | 0xB5, 0x50, 0x02, 0x82,
275 | 0xA3, 0xE8, 0xA3, 0xB8,
276 | 0xA4, 0x38, 0xA4, 0x28,
277 | 0xA6, 0x48, 0xA4, 0x48,
278 | 0xA7, 0x88, 0xA7, 0x48,
279 | 0xAC, 0x10, 0xA7, 0x90,
280 | 0x99, 0xBC, 0x99, 0xB4,
281 | 0x9A, 0xFC, 0x9A, 0xBC,
282 | 0x00, 0x00, 0x00, 0x00,
283 | 0x00, 0x00, 0x00, 0x00,
284 | 0x00, 0x00, 0x00, 0x00,
285 | 0x00, 0x00, 0x00, 0x00,
286 | 0x00, 0x00, 0x00, 0x00,
287 | 0x00, 0x00, 0x00, 0x00,
288 | 0x00, 0x00, 0x00, 0x00,
289 | 0x00, 0x00, 0x00, 0x00,
290 | 0x00, 0x00, 0x00, 0x00,
291 | 0x00, 0x00, 0x00, 0x00,
292 | 0x00, 0x00, 0x00, 0x00,
293 | 0x00, 0x00, 0x00, 0x00,
294 | 0x00, 0x00, 0x00, 0x00,
295 | 0xB5, 0xA0, 0x02, 0x82,
296 | 0x00, 0x88, 0x03, 0x00,
297 | 0x00, 0x82, 0x00, 0x82,
298 | 0x04, 0x04, 0x04, 0x08,
299 | 0x00, 0x80, 0x04, 0x01,
300 | 0x09, 0x02, 0x09, 0x08,
301 | 0x04, 0x04, 0x00, 0x80,
302 | 0x04, 0x01, 0x04, 0x01,
303 | 0x00, 0x00, 0x00, 0x00,
304 | 0x00, 0x00, 0x00, 0x00,
305 | 0x00, 0x00, 0x00, 0x00,
306 | 0x00, 0x00, 0x00, 0x00,
307 | 0x00, 0x00, 0x00, 0x00,
308 | 0x00, 0x00, 0x00, 0x00,
309 | 0x00, 0x00, 0x00, 0x00,
310 | 0x00, 0x00, 0x00, 0x00,
311 | 0x00, 0x00, 0x00, 0x00,
312 | 0x00, 0x00, 0x00, 0x00,
313 | 0x00, 0x00, 0x00, 0x00,
314 | 0x00, 0x00, 0x00, 0x00,
315 | 0x00, 0x00, 0x00, 0x00,
316 | 0xB5, 0xF0, 0x00, 0x40,
317 | 0x00, 0x04, 0x00, 0x00,
318 | 0xB3, 0x9C, 0x01, 0x00,
319 | 0x40, 0x00, 0x05, 0x1E,
320 | 0x02, 0x1B, 0x08, 0x7C,
321 | 0x80, 0x00, 0x12, 0x01,
322 | 0x00, 0x01, 0x08, 0x00,
323 | 0xB6, 0xC0, 0x00, 0xC0,
324 | 0x00, 0x00, 0x60, 0x00,
325 | 0x00, 0x00, 0x20, 0x00,
326 | 0x00, 0x00, 0x00, 0x00,
327 | 0xAE, 0xA8, 0x00, 0x40,
328 | 0x00, 0x00, 0x04, 0x05,
329 | 0xAE, 0xAC, 0x00, 0x80,
330 | 0x01, 0x00, 0x01, 0x00,
331 | 0x00, 0x02, 0x00, 0x00,
332 | 0xAE, 0xB4, 0x00, 0x40,
333 | 0x00, 0x00, 0x00, 0x00,
334 | 0xAE, 0xB8, 0x00, 0x81,
335 | 0x00, 0x00, 0x00, 0x00,
336 | 0x00, 0x00, 0x00, 0x00,
337 | 0xAE, 0xC0, 0x00, 0x81,
338 | 0x00, 0x00, 0x00, 0x00,
339 | 0x00, 0x00, 0x00, 0x00,
340 | 0xAE, 0xC8, 0x00, 0x81,
341 | 0x08, 0x01, 0x01, 0x08,
342 | 0x00, 0x00, 0x00, 0x08,
343 | 0xAE, 0xD0, 0x00, 0x81,
344 | 0x01, 0x08, 0x08, 0x08,
345 | 0x00, 0x00, 0x00, 0x01,
346 | 0xB5, 0xF4, 0x00, 0x80,
347 | 0x00, 0x00, 0x00, 0x00,
348 | 0x00, 0x00, 0x00, 0x00,
349 | 0xB5, 0xFC, 0x00, 0x80,
350 | 0x00, 0x00, 0x00, 0x00,
351 | 0x00, 0x00, 0x00, 0x00,
352 | 0xB6, 0x04, 0x00, 0x40,
353 | 0x00, 0x00, 0x00, 0x00,
354 | 0xB6, 0x08, 0x00, 0x44,
355 | 0x00, 0x00, 0x00, 0x00,
356 | 0x00, 0x00, 0x00, 0x00,
357 | 0x00, 0x00, 0x00, 0x00,
358 | 0x00, 0x00, 0x00, 0x00,
359 | 0xB6, 0x18, 0x00, 0x44,
360 | 0x00, 0x00, 0x00, 0x00,
361 | 0x00, 0x00, 0x00, 0x00,
362 | 0x00, 0x00, 0x00, 0x00,
363 | 0x00, 0x00, 0x00, 0x00,
364 | 0xB6, 0x28, 0x00, 0x44,
365 | 0x00, 0x00, 0x00, 0x00,
366 | 0x00, 0x00, 0x00, 0x00,
367 | 0x00, 0x00, 0x00, 0x00,
368 | 0x00, 0x00, 0x00, 0x00,
369 | 0xB6, 0x38, 0x00, 0x44,
370 | 0x00, 0x00, 0x00, 0x00,
371 | 0x00, 0x00, 0x00, 0x00,
372 | 0x00, 0x00, 0x00, 0x00,
373 | 0x00, 0x00, 0x00, 0x00,
374 | 0xB6, 0x48, 0x01, 0x00,
375 | 0x00, 0x00, 0x00, 0x00,
376 | 0x00, 0x00, 0x00, 0x00,
377 | 0x00, 0x00, 0x00, 0x00,
378 | 0x00, 0x00, 0x00, 0x00,
379 | 0xB6, 0x58, 0x01, 0x00,
380 | 0x00, 0x00, 0x00, 0x00,
381 | 0x00, 0x00, 0x00, 0x00,
382 | 0x00, 0x00, 0x00, 0x00,
383 | 0x00, 0x00, 0x00, 0x00,
384 | 0xB6, 0x68, 0x01, 0x00,
385 | 0x00, 0x00, 0x00, 0x00,
386 | 0x00, 0x00, 0x00, 0x00,
387 | 0x00, 0x00, 0x00, 0x00,
388 | 0x00, 0x00, 0x00, 0x00,
389 | 0x54, 0x70, 0x00, 0x80,
390 | 0x00, 0x00, 0x00, 0x00,
391 | 0x00, 0x00, 0x00, 0x02,
392 | 0x00, 0x00, 0x00, 0x0F,
393 | 0x00, 0x01, 0x03, 0xD4
394 | };
395 |
396 | #ifdef __cplusplus
397 | }
398 | #endif
399 |
400 | #endif /* VL53L8CX_PLUGIN_XTALK_H_ */
401 |
--------------------------------------------------------------------------------