├── .github └── workflows │ └── Continuous-integration.yml ├── LICENSE.md ├── README.md ├── examples ├── VL53L7CX_HelloWorld │ └── VL53L7CX_HelloWorld.ino └── VL53L7CX_ThresholdDetection │ └── VL53L7CX_ThresholdDetection.ino ├── extras └── codespell-ignore-words-list.txt ├── keywords.txt ├── library.properties └── src ├── vl53l7cx_api.cpp ├── vl53l7cx_api.h ├── vl53l7cx_buffers.h ├── vl53l7cx_class.h ├── vl53l7cx_platform.cpp ├── vl53l7cx_platform.h ├── vl53l7cx_platform_config.h ├── vl53l7cx_platform_config_default.h ├── vl53l7cx_plugin_detection_thresholds.cpp ├── vl53l7cx_plugin_detection_thresholds.h ├── vl53l7cx_plugin_motion_indicator.cpp ├── vl53l7cx_plugin_motion_indicator.h ├── vl53l7cx_plugin_xtalk.cpp └── vl53l7cx_plugin_xtalk.h /.github/workflows/Continuous-integration.yml: -------------------------------------------------------------------------------- 1 | name: VL53L7CX 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 | # In the event of a false positive, add the word in all lower case to this file: 48 | ignore_words_file: ./extras/codespell-ignore-words-list.txt 49 | lib_build: 50 | runs-on: ubuntu-latest 51 | name: Library compilation 52 | steps: 53 | 54 | # First of all, clone the repo using the checkout action. 55 | - name: Checkout 56 | uses: actions/checkout@main 57 | 58 | - name: Compilation 59 | id: compile 60 | uses: stm32duino/actions/compile-examples@main 61 | with: 62 | board-pattern: "NUCLEO_L476RG" 63 | 64 | # Use the output from the `Compilation` step 65 | - name: Compilation Errors 66 | if: failure() 67 | run: | 68 | cat ${{ steps.compile.outputs.compile-result }} 69 | exit 1 70 | -------------------------------------------------------------------------------- /LICENSE.md: -------------------------------------------------------------------------------- 1 | COPYRIGHT(c) 2021 STMicroelectronics 2 | 3 | Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: 4 | 5 | Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. 6 | Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. 7 | Neither the name of STMicroelectronics nor the names of its contributors may be used to endorse or promote products derived from this software without specific prior written permission. 8 | THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 9 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # VL53L7CX 2 | Arduino library to support the VL53L7CX Time-of-Flight 8x8 multizone ranging sensor with wide field view. 3 | 4 | ## API 5 | 6 | This sensor uses I2C to communicate. And I2C 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 | 9 | ## Examples 10 | 11 | The examples contained in this library are based on VL53L7CX-SATEL sensor board. You need to connect the VL53L7CX-SATEL sensor board directly to the Nucleo board with wires as explained below: 12 | - pin 1 (GND) of the VL53L7CX satellite connected to GND of the Nucleo board 13 | - pin 2 (IOVDD) of the VL53L7CX satellite connected to 3V3 pin of the Nucleo board 14 | - pin 3 (AVDD) of the VL53L7CX satellite connected to 5V pin of the Nucleo board 15 | - pin 4 (PWREN) of the VL53L7CX satellite connected to pin A5 of the Nucleo board 16 | - pin 5 (LPn) of the VL53L7CX satellite connected to pin A3 of the Nucleo board 17 | - pin 6 (SCL) of the VL53L7CX satellite connected to pin D15 (SCL) of the Nucleo board 18 | - pin 7 (SDA) of the VL53L7CX satellite connected to pin D14 (SDA) of the Nucleo board 19 | - pin 8 (I2C_RST) of the VL53L7CX satellite connected to pin A1 of the Nucleo board 20 | - pin 9 (INT) of the VL53L7CX satellite connected to pin A2 of the Nucleo board 21 | 22 | There are 2 examples with the VL53L7CX library: 23 | 24 | * VL53L7CX_HelloWorld: This example code is to show how to get multizone detection and proximity values of the VL53L7CX satellite sensor in polling mode. 25 | 26 | * VL53L7CX_ThresholdsDetection: This example code is to show how to configure the thresholds detection of the VL53L7CX satellite sensor. 27 | 28 | ## Documentation 29 | 30 | You can find the source files at 31 | https://github.com/stm32duino/VL53L7CX 32 | 33 | The VL53L7CX datasheet is available at 34 | https://www.st.com/en/imaging-and-photonics-solutions/VL53L7CX.html 35 | -------------------------------------------------------------------------------- /examples/VL53L7CX_HelloWorld/VL53L7CX_HelloWorld.ino: -------------------------------------------------------------------------------- 1 | /** 2 | ****************************************************************************** 3 | * @file VL53L7CX_HelloWorld.ino 4 | * @author STMicroelectronics 5 | * @version V1.0.0 6 | * @date 16 January 2023 7 | * @brief Arduino test application for STMicroelectronics VL53L7CX 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) 2021 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 VL53L7CX satellite sensor directly to the Nucleo board with wires as explained below: 42 | * pin 1 (GND) of the VL53L7CX satellite connected to GND of the Nucleo board 43 | * pin 2 (IOVDD) of the VL53L7CX satellite connected to 3V3 pin of the Nucleo board 44 | * pin 3 (AVDD) of the VL53L7CX satellite connected to 5V pin of the Nucleo board 45 | * pin 4 (PWREN) of the VL53L7CX satellite connected to pin A5 of the Nucleo board 46 | * pin 5 (LPn) of the VL53L7CX satellite connected to pin A3 of the Nucleo board 47 | * pin 6 (SCL) of the VL53L7CX satellite connected to pin D15 (SCL) of the Nucleo board 48 | * pin 7 (SDA) of the VL53L7CX satellite connected to pin D14 (SDA) of the Nucleo board 49 | * pin 8 (I2C_RST) of the VL53L7CX satellite connected to pin A1 of the Nucleo board 50 | * pin 9 (INT) of the VL53L7CX satellite connected to pin A2 of the Nucleo board 51 | */ 52 | 53 | /* Includes ------------------------------------------------------------------*/ 54 | #include 55 | #include 56 | #include 57 | 58 | 59 | #ifdef ARDUINO_SAM_DUE 60 | #define DEV_I2C Wire1 61 | #else 62 | #define DEV_I2C Wire 63 | #endif 64 | #define SerialPort Serial 65 | 66 | #define LPN_PIN A3 67 | #define I2C_RST_PIN A1 68 | #define PWREN_PIN A5 69 | 70 | void print_result(VL53L7CX_ResultsData *Result); 71 | void clear_screen(void); 72 | void handle_cmd(uint8_t cmd); 73 | void display_commands_banner(void); 74 | 75 | // Components. 76 | VL53L7CX sensor_vl53l7cx_top(&DEV_I2C, LPN_PIN, I2C_RST_PIN); 77 | 78 | bool EnableAmbient = false; 79 | bool EnableSignal = false; 80 | uint8_t res = VL53L7CX_RESOLUTION_4X4; 81 | char report[256]; 82 | 83 | /* Setup ---------------------------------------------------------------------*/ 84 | void setup() 85 | { 86 | 87 | // Enable PWREN pin if present 88 | if (PWREN_PIN >= 0) { 89 | pinMode(PWREN_PIN, OUTPUT); 90 | digitalWrite(PWREN_PIN, HIGH); 91 | delay(10); 92 | } 93 | 94 | // Initialize serial for output. 95 | SerialPort.begin(460800); 96 | 97 | // Initialize I2C bus. 98 | DEV_I2C.begin(); 99 | 100 | // Configure VL53L7CX component. 101 | sensor_vl53l7cx_top.begin(); 102 | 103 | sensor_vl53l7cx_top.init_sensor(); 104 | 105 | // Start Measurements 106 | sensor_vl53l7cx_top.vl53l7cx_start_ranging(); 107 | } 108 | 109 | void loop() 110 | { 111 | VL53L7CX_ResultsData Results; 112 | uint8_t NewDataReady = 0; 113 | uint8_t status; 114 | 115 | do { 116 | status = sensor_vl53l7cx_top.vl53l7cx_check_data_ready(&NewDataReady); 117 | } while (!NewDataReady); 118 | 119 | if ((!status) && (NewDataReady != 0)) { 120 | status = sensor_vl53l7cx_top.vl53l7cx_get_ranging_data(&Results); 121 | print_result(&Results); 122 | } 123 | 124 | if (Serial.available()>0) 125 | { 126 | handle_cmd(Serial.read()); 127 | } 128 | delay(1000); 129 | } 130 | 131 | void print_result(VL53L7CX_ResultsData *Result) 132 | { 133 | int8_t i, j, k, l; 134 | uint8_t 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 < VL53L7CX_NB_TARGET_PER_ZONE; l++) 144 | { 145 | snprintf(report, sizeof(report)," \033[38;5;10m%20s\033[0m : %20s\n", "Distance [mm]", "Status"); 146 | SerialPort.print(report); 147 | 148 | if(EnableAmbient || EnableSignal) 149 | { 150 | snprintf(report, sizeof(report)," %20s : %20s\n", "Signal [kcps/spad]", "Ambient [kcps/spad]"); 151 | SerialPort.print(report); 152 | } 153 | } 154 | 155 | SerialPort.print("\n\n"); 156 | 157 | for (j = 0; j < number_of_zones; j += zones_per_line) 158 | { 159 | for (i = 0; i < zones_per_line; i++) 160 | SerialPort.print(" -----------------"); 161 | SerialPort.print("\n"); 162 | 163 | for (i = 0; i < zones_per_line; i++) 164 | SerialPort.print("| "); 165 | SerialPort.print("|\n"); 166 | 167 | for (l = 0; l < VL53L7CX_NB_TARGET_PER_ZONE; l++) 168 | { 169 | // Print distance and status 170 | for (k = (zones_per_line - 1); k >= 0; k--) 171 | { 172 | if (Result->nb_target_detected[j+k]>0) 173 | { 174 | snprintf(report, sizeof(report),"| \033[38;5;10m%5ld\033[0m : %5ld ", 175 | (long)Result->distance_mm[(VL53L7CX_NB_TARGET_PER_ZONE * (j+k)) + l], 176 | (long)Result->target_status[(VL53L7CX_NB_TARGET_PER_ZONE * (j+k)) + l]); 177 | SerialPort.print(report); 178 | } 179 | else 180 | { 181 | snprintf(report, sizeof(report),"| %5s : %5s ", "X", "X"); 182 | SerialPort.print(report); 183 | } 184 | } 185 | SerialPort.print("|\n"); 186 | 187 | if (EnableAmbient || EnableSignal ) 188 | { 189 | // Print Signal and Ambient 190 | for (k = (zones_per_line - 1); k >= 0; k--) 191 | { 192 | if (Result->nb_target_detected[j+k]>0) 193 | { 194 | if (EnableSignal) 195 | { 196 | snprintf(report, sizeof(report),"| %5ld : ", (long)Result->signal_per_spad[(VL53L7CX_NB_TARGET_PER_ZONE * (j+k)) + l]); 197 | SerialPort.print(report); 198 | } 199 | else 200 | { 201 | snprintf(report, sizeof(report),"| %5s : ", "X"); 202 | SerialPort.print(report); 203 | } 204 | if (EnableAmbient) 205 | { 206 | snprintf(report, sizeof(report),"%5ld ", (long)Result->ambient_per_spad[j+k]); 207 | SerialPort.print(report); 208 | } 209 | else 210 | { 211 | snprintf(report, sizeof(report),"%5s ", "X"); 212 | SerialPort.print(report); 213 | } 214 | } 215 | else 216 | { 217 | snprintf(report, sizeof(report),"| %5s : %5s ", "X", "X"); 218 | SerialPort.print(report); 219 | } 220 | } 221 | SerialPort.print("|\n"); 222 | } 223 | } 224 | } 225 | for (i = 0; i < zones_per_line; i++) 226 | SerialPort.print(" -----------------"); 227 | SerialPort.print("\n"); 228 | } 229 | 230 | void toggle_resolution(void) 231 | { 232 | sensor_vl53l7cx_top.vl53l7cx_stop_ranging(); 233 | 234 | switch (res) 235 | { 236 | case VL53L7CX_RESOLUTION_4X4: 237 | res = VL53L7CX_RESOLUTION_8X8; 238 | break; 239 | 240 | case VL53L7CX_RESOLUTION_8X8: 241 | res = VL53L7CX_RESOLUTION_4X4; 242 | break; 243 | 244 | default: 245 | break; 246 | } 247 | sensor_vl53l7cx_top.vl53l7cx_set_resolution(res); 248 | sensor_vl53l7cx_top.vl53l7cx_start_ranging(); 249 | } 250 | 251 | void toggle_signal_and_ambient(void) 252 | { 253 | EnableAmbient = (EnableAmbient) ? false : true; 254 | EnableSignal = (EnableSignal) ? false : true; 255 | } 256 | 257 | void clear_screen(void) 258 | { 259 | snprintf(report, sizeof(report),"%c[2J", 27); /* 27 is ESC command */ 260 | SerialPort.print(report); 261 | } 262 | 263 | void display_commands_banner(void) 264 | { 265 | snprintf(report, sizeof(report),"%c[2H", 27); /* 27 is ESC command */ 266 | SerialPort.print(report); 267 | 268 | Serial.print("53L7A1 Simple Ranging demo application\n"); 269 | Serial.print("--------------------------------------\n\n"); 270 | 271 | Serial.print("Use the following keys to control application\n"); 272 | Serial.print(" 'r' : change resolution\n"); 273 | Serial.print(" 's' : enable signal and ambient\n"); 274 | Serial.print(" 'c' : clear screen\n"); 275 | Serial.print("\n"); 276 | } 277 | 278 | void handle_cmd(uint8_t cmd) 279 | { 280 | switch (cmd) 281 | { 282 | case 'r': 283 | toggle_resolution(); 284 | clear_screen(); 285 | break; 286 | 287 | case 's': 288 | toggle_signal_and_ambient(); 289 | clear_screen(); 290 | break; 291 | 292 | case 'c': 293 | clear_screen(); 294 | break; 295 | 296 | default: 297 | break; 298 | } 299 | } 300 | -------------------------------------------------------------------------------- /examples/VL53L7CX_ThresholdDetection/VL53L7CX_ThresholdDetection.ino: -------------------------------------------------------------------------------- 1 | /** 2 | ****************************************************************************** 3 | * @file VL53L7CX_ThresholdDetection.ino 4 | * @author STMicroelectronics 5 | * @version V1.0.0 6 | * @date 16 January 2023 7 | * @brief Arduino test application for the STMicrolectronics VL53L7CX 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) 2021 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 VL53L7CX satellite sensor directly to the Nucleo board with wires as explained below: 42 | * pin 1 (GND) of the VL53L7CX satellite connected to GND of the Nucleo board 43 | * pin 2 (IOVDD) of the VL53L7CX satellite connected to 3V3 pin of the Nucleo board 44 | * pin 3 (AVDD) of the VL53L7CX satellite connected to 5V pin of the Nucleo board 45 | * pin 4 (PWREN) of the VL53L7CX satellite connected to pin A5 of the Nucleo board 46 | * pin 5 (LPn) of the VL53L7CX satellite connected to pin A3 of the Nucleo board 47 | * pin 6 (SCL) of the VL53L7CX satellite connected to pin D15 (SCL) of the Nucleo board 48 | * pin 7 (SDA) of the VL53L7CX satellite connected to pin D14 (SDA) of the Nucleo board 49 | * pin 8 (I2C_RST) of the VL53L7CX satellite connected to pin A1 of the Nucleo board 50 | * pin 9 (INT) of the VL53L7CX satellite connected to pin A2 of the Nucleo board 51 | */ 52 | 53 | /* Includes ------------------------------------------------------------------*/ 54 | #include 55 | #include 56 | #include 57 | 58 | #ifdef ARDUINO_SAM_DUE 59 | #define DEV_I2C Wire1 60 | #else 61 | #define DEV_I2C Wire 62 | #endif 63 | #define SerialPort Serial 64 | 65 | #define LPN_PIN A3 66 | #define I2C_RST_PIN A1 67 | #define PWREN_PIN A5 68 | #define INT_PIN A2 69 | 70 | void measure(void); 71 | void print_result(VL53L7CX_ResultsData *Result); 72 | 73 | // Component. 74 | VL53L7CX sensor_vl53l7cx_top(&DEV_I2C, LPN_PIN, I2C_RST_PIN); 75 | 76 | bool EnableAmbient = false; 77 | bool EnableSignal = false; 78 | uint8_t res = VL53L7CX_RESOLUTION_4X4; 79 | char report[256]; 80 | volatile int interruptCount = 0; 81 | uint8_t i; 82 | 83 | /* Setup ---------------------------------------------------------------------*/ 84 | 85 | void setup() 86 | { 87 | 88 | VL53L7CX_DetectionThresholds thresholds[VL53L7CX_NB_THRESHOLDS]; 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 | // Set interrupt pin 104 | pinMode(INT_PIN, INPUT_PULLUP); 105 | attachInterrupt(INT_PIN, measure, FALLING); 106 | 107 | // Configure VL53L7CX component. 108 | sensor_vl53l7cx_top.begin(); 109 | 110 | sensor_vl53l7cx_top.init_sensor(); 111 | 112 | // Disable thresholds detection. 113 | sensor_vl53l7cx_top.vl53l7cx_set_detection_thresholds_enable(0U); 114 | 115 | // Set all values to 0. 116 | memset(&thresholds, 0, sizeof(thresholds)); 117 | 118 | // Configure thresholds on each active zone 119 | for (i = 0; i < res; i++) 120 | { 121 | thresholds[i].zone_num = i; 122 | thresholds[i].measurement = VL53L7CX_DISTANCE_MM; 123 | thresholds[i].type = VL53L7CX_IN_WINDOW; 124 | thresholds[i].mathematic_operation = VL53L7CX_OPERATION_NONE; 125 | thresholds[i].param_low_thresh = 200; 126 | thresholds[i].param_high_thresh = 600; 127 | } 128 | 129 | // Last threshold must be clearly indicated. 130 | thresholds[i].zone_num |= VL53L7CX_LAST_THRESHOLD; 131 | 132 | // Send array of thresholds to the sensor. 133 | sensor_vl53l7cx_top.vl53l7cx_set_detection_thresholds(thresholds); 134 | 135 | // Enable thresholds detection. 136 | sensor_vl53l7cx_top.vl53l7cx_set_detection_thresholds_enable(1U); 137 | 138 | // Start Measurements. 139 | sensor_vl53l7cx_top.vl53l7cx_start_ranging(); 140 | } 141 | 142 | void loop() 143 | { 144 | VL53L7CX_ResultsData Results; 145 | uint8_t NewDataReady = 0; 146 | uint8_t status; 147 | 148 | do { 149 | status = sensor_vl53l7cx_top.vl53l7cx_check_data_ready(&NewDataReady); 150 | } while (!NewDataReady); 151 | 152 | if ((!status) && (NewDataReady != 0)&& interruptCount ) { 153 | interruptCount = 0; 154 | status = sensor_vl53l7cx_top.vl53l7cx_get_ranging_data(&Results); 155 | print_result(&Results); 156 | } 157 | 158 | } 159 | 160 | void print_result(VL53L7CX_ResultsData *Result) 161 | { 162 | int8_t i, j, k, l; 163 | uint8_t zones_per_line; 164 | uint8_t number_of_zones = res; 165 | 166 | zones_per_line = (number_of_zones == 16) ? 4 : 8; 167 | 168 | snprintf(report, sizeof(report),"%c[2H", 27); /* 27 is ESC command */ 169 | SerialPort.print(report); 170 | SerialPort.print("53L7A1 Threshold Detection demo application\n"); 171 | SerialPort.print("-------------------------------------------\n\n"); 172 | SerialPort.print("Cell Format :\n\n"); 173 | 174 | for (l = 0; l < VL53L7CX_NB_TARGET_PER_ZONE; l++) 175 | { 176 | snprintf(report, sizeof(report)," \033[38;5;10m%20s\033[0m : %20s\n", "Distance [mm]", "Status"); 177 | SerialPort.print(report); 178 | 179 | if(EnableAmbient || EnableSignal) 180 | { 181 | snprintf(report, sizeof(report)," %20s : %20s\n", "Signal [kcps/spad]", "Ambient [kcps/spad]"); 182 | SerialPort.print(report); 183 | } 184 | } 185 | 186 | SerialPort.print("\n\n"); 187 | 188 | for (j = 0; j < number_of_zones; j += zones_per_line) 189 | { 190 | for (i = 0; i < zones_per_line; i++) 191 | SerialPort.print(" -----------------"); 192 | SerialPort.print("\n"); 193 | 194 | for (i = 0; i < zones_per_line; i++) 195 | SerialPort.print("| "); 196 | SerialPort.print("|\n"); 197 | 198 | for (l = 0; l < VL53L7CX_NB_TARGET_PER_ZONE; l++) 199 | { 200 | // Print distance and status. 201 | for (k = (zones_per_line - 1); k >= 0; k--) 202 | { 203 | if (Result->nb_target_detected[j+k]>0) 204 | { 205 | snprintf(report, sizeof(report),"| \033[38;5;10m%5ld\033[0m : %5ld ", 206 | (long)Result->distance_mm[(VL53L7CX_NB_TARGET_PER_ZONE * (j+k)) + l], 207 | (long)Result->target_status[(VL53L7CX_NB_TARGET_PER_ZONE * (j+k)) + l]); 208 | SerialPort.print(report); 209 | } 210 | else 211 | { 212 | snprintf(report, sizeof(report),"| %5s : %5s ", "X", "X"); 213 | SerialPort.print(report); 214 | } 215 | } 216 | SerialPort.print("|\n"); 217 | 218 | if (EnableAmbient || EnableSignal ) 219 | { 220 | // Print Signal and Ambient. 221 | for (k = (zones_per_line - 1); k >= 0; k--) 222 | { 223 | if (Result->nb_target_detected[j+k]>0) 224 | { 225 | if (EnableSignal) 226 | { 227 | snprintf(report, sizeof(report),"| %5ld : ", (long)Result->signal_per_spad[(VL53L7CX_NB_TARGET_PER_ZONE * (j+k)) + l]); 228 | SerialPort.print(report); 229 | } 230 | else 231 | { 232 | snprintf(report, sizeof(report),"| %5s : ", "X"); 233 | SerialPort.print(report); 234 | } 235 | if (EnableAmbient) 236 | { 237 | snprintf(report, sizeof(report),"%5ld ", (long)Result->ambient_per_spad[j+k]); 238 | SerialPort.print(report); 239 | } 240 | else 241 | { 242 | snprintf(report, sizeof(report),"%5s ", "X"); 243 | SerialPort.print(report); 244 | } 245 | } 246 | else 247 | { 248 | snprintf(report, sizeof(report),"| %5s : %5s ", "X", "X"); 249 | SerialPort.print(report); 250 | } 251 | } 252 | SerialPort.print("|\n"); 253 | } 254 | } 255 | } 256 | for (i = 0; i < zones_per_line; i++) 257 | SerialPort.print(" -----------------"); 258 | SerialPort.print("\n"); 259 | } 260 | 261 | void measure(void) 262 | { 263 | interruptCount = 1; 264 | } 265 | -------------------------------------------------------------------------------- /extras/codespell-ignore-words-list.txt: -------------------------------------------------------------------------------- 1 | ois -------------------------------------------------------------------------------- /keywords.txt: -------------------------------------------------------------------------------- 1 | ####################################### 2 | # Syntax Coloring Map For VL53L7CX 3 | ####################################### 4 | 5 | ####################################### 6 | # Datatypes (KEYWORD1) 7 | ####################################### 8 | 9 | VL53L7CX KEYWORD1 10 | 11 | ####################################### 12 | # Methods and Functions (KEYWORD2) 13 | ####################################### 14 | 15 | begin KEYWORD2 16 | end KEYWORD2 17 | init_sensor KEYWORD2 18 | vl53l7cx_on KEYWORD2 19 | vl53l7cx_off KEYWORD2 20 | vl53l7cx_is_alive KEYWORD2 21 | vl53l7cx_init KEYWORD2 22 | vl53l7cx_set_i2c_address KEYWORD2 23 | vl53l7cx_get_power_mode KEYWORD2 24 | vl53l7cx_set_power_mode KEYWORD2 25 | vl53l7cx_start_ranging KEYWORD2 26 | vl53l7cx_stop_ranging KEYWORD2 27 | vl53l7cx_check_data_ready KEYWORD2 28 | vl53l7cx_get_ranging_data KEYWORD2 29 | vl53l7cx_get_resolution KEYWORD2 30 | vl53l7cx_set_resolution KEYWORD2 31 | vl53l7cx_get_ranging_frequency_hz KEYWORD2 32 | vl53l7cx_set_ranging_frequency_hz KEYWORD2 33 | vl53l7cx_get_integration_time_ms KEYWORD2 34 | vl53l7cx_set_integration_time_ms KEYWORD2 35 | vl53l7cx_get_sharpener_percent KEYWORD2 36 | vl53l7cx_set_sharpener_percent KEYWORD2 37 | vl53l7cx_get_target_order KEYWORD2 38 | vl53l7cx_set_target_order KEYWORD2 39 | vl53l7cx_get_ranging_mode KEYWORD2 40 | vl53l7cx_set_ranging_mode KEYWORD2 41 | vl53l7cx_dci_read_data KEYWORD2 42 | vl53l7cx_dci_write_data KEYWORD2 43 | vl53l7cx_dci_replace_data KEYWORD2 44 | vl53l7cx_get_detection_thresholds_enable KEYWORD2 45 | vl53l7cx_set_detection_thresholds_enable KEYWORD2 46 | vl53l7cx_get_detection_thresholds KEYWORD2 47 | vl53l7cx_set_detection_thresholds KEYWORD2 48 | vl53l7cx_motion_indicator_init KEYWORD2 49 | vl53l7cx_motion_indicator_set_distance_motion KEYWORD2 50 | vl53l7cx_motion_indicator_set_resolution KEYWORD2 51 | vl53l7cx_calibrate_xtalk KEYWORD2 52 | vl53l7cx_get_caldata_xtalk KEYWORD2 53 | vl53l7cx_set_caldata_xtalk KEYWORD2 54 | vl53l7cx_get_xtalk_margin KEYWORD2 55 | vl53l7cx_set_xtalk_margin KEYWORD2 56 | SwapBuffer KEYWORD2 57 | get_stream_count KEYWORD2 58 | 59 | ####################################### 60 | # Constants (LITERAL1) 61 | ####################################### 62 | 63 | DEFAULT_I2C_BUFFER_LEN LITERAL1 64 | VL53L7CX_NB_TARGET_PER_ZONE LITERAL1 65 | VL53L7CX_API_REVISION LITERAL1 66 | VL53L7CX_DEFAULT_I2C_ADDRESS LITERAL1 67 | VL53L7CX_RESOLUTION_4X4 LITERAL1 68 | VL53L7CX_RESOLUTION_8X8 LITERAL1 69 | VL53L7CX_TARGET_ORDER_CLOSEST LITERAL1 70 | VL53L7CX_TARGET_ORDER_STRONGEST LITERAL1 71 | VL53L7CX_RANGING_MODE_CONTINUOUS LITERAL1 72 | VL53L7CX_RANGING_MODE_AUTONOMOUS LITERAL1 73 | VL53L7CX_POWER_MODE_SLEEP LITERAL1 74 | VL53L7CX_POWER_MODE_WAKEUP LITERAL1 75 | VL53L7CX_STATUS_OK LITERAL1 76 | VL53L7CX_MCU_ERROR LITERAL1 77 | VL53L7CX_STATUS_INVALID_PARAM LITERAL1 78 | VL53L7CX_STATUS_ERROR LITERAL1 79 | VL53L7CX_START_BH LITERAL1 80 | VL53L7CX_METADATA_BH LITERAL1 81 | VL53L7CX_COMMONDATA_BH LITERAL1 82 | VL53L7CX_AMBIENT_RATE_BH LITERAL1 83 | VL53L7CX_SPAD_COUNT_BH LITERAL1 84 | VL53L7CX_NB_TARGET_DETECTED_BH LITERAL1 85 | VL53L7CX_SIGNAL_RATE_BH LITERAL1 86 | VL53L7CX_RANGE_SIGMA_MM_BH LITERAL1 87 | VL53L7CX_DISTANCE_BH LITERAL1 88 | VL53L7CX_REFLECTANCE_BH LITERAL1 89 | VL53L7CX_TARGET_STATUS_BH LITERAL1 90 | VL53L7CX_MOTION_DETECT_BH LITERAL1 91 | VL53L7CX_METADATA_IDX LITERAL1 92 | VL53L7CX_SPAD_COUNT_IDX LITERAL1 93 | VL53L7CX_AMBIENT_RATE_IDX LITERAL1 94 | VL53L7CX_NB_TARGET_DETECTED_IDX LITERAL1 95 | VL53L7CX_SIGNAL_RATE_IDX LITERAL1 96 | VL53L7CX_RANGE_SIGMA_MM_IDX LITERAL1 97 | VL53L7CX_DISTANCE_IDX LITERAL1 98 | VL53L7CX_REFLECTANCE_EST_PC_IDX LITERAL1 99 | VL53L7CX_TARGET_STATUS_IDX LITERAL1 100 | VL53L7CX_MOTION_DETEC_IDX LITERAL1 101 | VL53L7CX_NVM_DATA_SIZE LITERAL1 102 | VL53L7CX_CONFIGURATION_SIZE LITERAL1 103 | VL53L7CX_OFFSET_BUFFER_SIZE LITERAL1 104 | VL53L7CX_XTALK_BUFFER_SIZE LITERAL1 105 | VL53L7CX_DCI_ZONE_CONFIG LITERAL1 106 | VL53L7CX_DCI_FREQ_HZ LITERAL1 107 | VL53L7CX_DCI_INT_TIME LITERAL1 108 | VL53L7CX_DCI_FW_NB_TARGET LITERAL1 109 | VL53L7CX_DCI_RANGING_MODE LITERAL1 110 | VL53L7CX_DCI_DSS_CONFIG LITERAL1 111 | VL53L7CX_DCI_TARGET_ORDER LITERAL1 112 | VL53L7CX_DCI_SHARPENER LITERAL1 113 | VL53L7CX_DCI_MOTION_DETECTOR_CFG LITERAL1 114 | VL53L7CX_DCI_SINGLE_RANGE LITERAL1 115 | VL53L7CX_DCI_OUTPUT_CONFIG LITERAL1 116 | VL53L7CX_DCI_OUTPUT_ENABLES LITERAL1 117 | VL53L7CX_DCI_OUTPUT_LIST LITERAL1 118 | VL53L7CX_DCI_PIPE_CONTROL LITERAL1 119 | VL53L7CX_UI_CMD_STATUS LITERAL1 120 | VL53L7CX_UI_CMD_START LITERAL1 121 | VL53L7CX_UI_CMD_END LITERAL1 122 | L5CX_AMB_SIZE LITERAL1 123 | L5CX_SPAD_SIZE LITERAL1 124 | L5CX_NTAR_SIZE LITERAL1 125 | L5CX_SPS_SIZE LITERAL1 126 | L5CX_SIGR_SIZE LITERAL1 127 | L5CX_DIST_SIZE LITERAL1 128 | L5CX_RFLEST_SIZE LITERAL1 129 | L5CX_STA_SIZE LITERAL1 130 | L5CX_MOT_SIZE LITERAL1 131 | VL53L7CX_MAX_RESULTS_SIZE LITERAL1 132 | VL53L7CX_TEMPORARY_BUFFER_SIZE LITERAL1 133 | VL53L7CX_FW_NBTAR_RANGING LITERAL1 134 | VL53L7CX_NB_THRESHOLDS LITERAL1 135 | VL53L7CX_DCI_DET_THRESH_CONFIG LITERAL1 136 | VL53L7CX_DCI_DET_THRESH_GLOBAL_CONFIG LITERAL1 137 | VL53L7CX_DCI_DET_THRESH_START LITERAL1 138 | VL53L7CX_DCI_DET_THRESH_VALID_STATUS LITERAL1 139 | VL53L7CX_LAST_THRESHOLD LITERAL1 140 | VL53L7CX_DISTANCE_MM LITERAL1 141 | VL53L7CX_SIGNAL_PER_SPAD_KCPS LITERAL1 142 | VL53L7CX_RANGE_SIGMA_MM LITERAL1 143 | VL53L7CX_AMBIENT_PER_SPAD_KCPS LITERAL1 144 | VL53L7CX_NB_TARGET_DETECTED LITERAL1 145 | VL53L7CX_TARGET_STATUS LITERAL1 146 | VL53L7CX_NB_SPADS_ENABLED LITERAL1 147 | VL53L7CX_MOTION_INDICATOR LITERAL1 148 | VL53L7CX_IN_WINDOW LITERAL1 149 | VL53L7CX_OUT_OF_WINDOW LITERAL1 150 | VL53L7CX_LESS_THAN_EQUAL_MIN_CHECKER LITERAL1 151 | VL53L7CX_GREATER_THAN_MAX_CHECKER LITERAL1 152 | VL53L7CX_EQUAL_MIN_CHECKER LITERAL1 153 | VL53L7CX_NOT_EQUAL_MIN_CHECKER LITERAL1 154 | VL53L7CX_OPERATION_NONE LITERAL1 155 | VL53L7CX_OPERATION_OR LITERAL1 156 | VL53L7CX_OPERATION_AND LITERAL1 157 | VL53L7CX_FW_NBTAR_XTALK LITERAL1 158 | VL53L7CX_DCI_CAL_CFG LITERAL1 159 | VL53L7CX_DCI_XTALK_CFG LITERAL1 160 | -------------------------------------------------------------------------------- /library.properties: -------------------------------------------------------------------------------- 1 | name=STM32duino VL53L7CX 2 | version=1.0.3 3 | author=STMicroelectronics 4 | maintainer=stm32duino 5 | sentence=Allows controlling the VL53L7CX (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/VL53L7CX 9 | architectures=stm32, sam 10 | -------------------------------------------------------------------------------- /src/vl53l7cx_api.cpp: -------------------------------------------------------------------------------- 1 | /** 2 | ****************************************************************************** 3 | * @file vl53l7cx_api.cpp 4 | * @author STMicroelectronics 5 | * @version V1.0.0 6 | * @date 13 January 2023 7 | * @brief Implementation of the VL53L7CX 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 | #include 39 | #include 40 | #include "vl53l7cx_class.h" 41 | #include "vl53l7cx_buffers.h" 42 | 43 | 44 | /** 45 | * @brief Inner function, not available outside this file. This function is used 46 | * to wait for an answer from VL53L7CX sensor. 47 | */ 48 | 49 | uint8_t VL53L7CX::_vl53l7cx_poll_for_answer( 50 | uint8_t size, 51 | uint8_t pos, 52 | uint16_t address, 53 | uint8_t mask, 54 | uint8_t expected_value) 55 | { 56 | uint8_t status = VL53L7CX_STATUS_OK; 57 | uint8_t timeout = 0; 58 | 59 | do { 60 | status |= RdMulti(&(p_dev->platform), address, 61 | p_dev->temp_buffer, size); 62 | status |= WaitMs(&(p_dev->platform), 10); 63 | 64 | if (timeout >= (uint8_t)200) { /* 2s timeout */ 65 | status |= (uint8_t)VL53L7CX_STATUS_TIMEOUT_ERROR; 66 | break; 67 | } else if ((size >= (uint8_t)4) 68 | && (p_dev->temp_buffer[2] >= (uint8_t)0x7f)) { 69 | status |= VL53L7CX_MCU_ERROR; 70 | break; 71 | } else { 72 | timeout++; 73 | } 74 | } while ((p_dev->temp_buffer[pos] & mask) != expected_value); 75 | 76 | return status; 77 | } 78 | 79 | /* 80 | * Inner function, not available outside this file. This function is used to 81 | * wait for the MCU to boot. 82 | */ 83 | uint8_t VL53L7CX::_vl53l7cx_poll_for_mcu_boot() 84 | { 85 | uint8_t go2_status0, go2_status1, status = VL53L7CX_STATUS_OK; 86 | uint16_t timeout = 0; 87 | 88 | do { 89 | status |= RdByte(&(p_dev->platform), 0x06, &go2_status0); 90 | if ((go2_status0 & (uint8_t)0x80) != (uint8_t)0) { 91 | status |= RdByte(&(p_dev->platform), 0x07, &go2_status1); 92 | status |= go2_status1; 93 | break; 94 | } 95 | (void)WaitMs(&(p_dev->platform), 1); 96 | timeout++; 97 | 98 | if ((go2_status0 & (uint8_t)0x1) != (uint8_t)0) { 99 | break; 100 | } 101 | 102 | } while (timeout < (uint16_t)500); 103 | 104 | return status; 105 | } 106 | 107 | /** 108 | * @brief Inner function, not available outside this file. This function is used 109 | * to set the offset data gathered from NVM. 110 | */ 111 | 112 | uint8_t VL53L7CX::_vl53l7cx_send_offset_data(uint8_t resolution) 113 | { 114 | uint8_t status = VL53L7CX_STATUS_OK; 115 | uint32_t signal_grid[64]; 116 | int16_t range_grid[64]; 117 | uint8_t dss_4x4[] = {0x0F, 0x04, 0x04, 0x00, 0x08, 0x10, 0x10, 0x07}; 118 | uint8_t footer[] = {0x00, 0x00, 0x00, 0x0F, 0x03, 0x01, 0x01, 0xE4}; 119 | int8_t i, j; 120 | uint16_t k; 121 | 122 | (void)memcpy(p_dev->temp_buffer, 123 | p_dev->offset_data, VL53L7CX_OFFSET_BUFFER_SIZE); 124 | 125 | /* Data extrapolation is required for 4X4 offset */ 126 | if (resolution == (uint8_t)VL53L7CX_RESOLUTION_4X4) { 127 | (void)memcpy(&(p_dev->temp_buffer[0x10]), dss_4x4, sizeof(dss_4x4)); 128 | SwapBuffer(p_dev->temp_buffer, VL53L7CX_OFFSET_BUFFER_SIZE); 129 | (void)memcpy(signal_grid, &(p_dev->temp_buffer[0x3C]), 130 | sizeof(signal_grid)); 131 | (void)memcpy(range_grid, &(p_dev->temp_buffer[0x140]), 132 | sizeof(range_grid)); 133 | 134 | for (j = 0; j < (int8_t)4; j++) { 135 | for (i = 0; i < (int8_t)4 ; i++) { 136 | signal_grid[i + (4 * j)] = 137 | (signal_grid[(2 * i) + (16 * j) + (int8_t)0] 138 | + signal_grid[(2 * i) + (16 * j) + (int8_t)1] 139 | + signal_grid[(2 * i) + (16 * j) + (int8_t)8] 140 | + signal_grid[(2 * i) + (16 * j) + (int8_t)9]) 141 | / (uint32_t)4; 142 | range_grid[i + (4 * j)] = 143 | (range_grid[(2 * i) + (16 * j)] 144 | + range_grid[(2 * i) + (16 * j) + 1] 145 | + range_grid[(2 * i) + (16 * j) + 8] 146 | + range_grid[(2 * i) + (16 * j) + 9]) 147 | / (int16_t)4; 148 | } 149 | } 150 | (void)memset(&range_grid[0x10], 0, (uint16_t)96); 151 | (void)memset(&signal_grid[0x10], 0, (uint16_t)192); 152 | (void)memcpy(&(p_dev->temp_buffer[0x3C]), 153 | signal_grid, sizeof(signal_grid)); 154 | (void)memcpy(&(p_dev->temp_buffer[0x140]), 155 | range_grid, sizeof(range_grid)); 156 | SwapBuffer(p_dev->temp_buffer, VL53L7CX_OFFSET_BUFFER_SIZE); 157 | } 158 | 159 | for (k = 0; k < (VL53L7CX_OFFSET_BUFFER_SIZE - (uint16_t)4); k++) { 160 | p_dev->temp_buffer[k] = p_dev->temp_buffer[k + (uint16_t)8]; 161 | } 162 | 163 | (void)memcpy(&(p_dev->temp_buffer[0x1E0]), footer, 8); 164 | status |= WrMulti(&(p_dev->platform), 0x2e18, p_dev->temp_buffer, 165 | VL53L7CX_OFFSET_BUFFER_SIZE); 166 | status |= _vl53l7cx_poll_for_answer(4, 1, 167 | VL53L7CX_UI_CMD_STATUS, 0xff, 0x03); 168 | 169 | return status; 170 | } 171 | 172 | /** 173 | * @brief Inner function, not available outside this file. This function is used 174 | * to set the Xtalk data from generic configuration, or user's calibration. 175 | */ 176 | 177 | uint8_t VL53L7CX::_vl53l7cx_send_xtalk_data(uint8_t resolution) 178 | { 179 | uint8_t status = VL53L7CX_STATUS_OK; 180 | uint8_t res4x4[] = {0x0F, 0x04, 0x04, 0x17, 0x08, 0x10, 0x10, 0x07}; 181 | uint8_t dss_4x4[] = {0x00, 0x78, 0x00, 0x08, 0x00, 0x00, 0x00, 0x08}; 182 | uint8_t profile_4x4[] = {0xA0, 0xFC, 0x01, 0x00}; 183 | uint32_t signal_grid[64]; 184 | int8_t i, j; 185 | 186 | (void)memcpy(p_dev->temp_buffer, &(p_dev->xtalk_data[0]), 187 | VL53L7CX_XTALK_BUFFER_SIZE); 188 | 189 | /* Data extrapolation is required for 4X4 Xtalk */ 190 | if (resolution == (uint8_t)VL53L7CX_RESOLUTION_4X4) { 191 | (void)memcpy(&(p_dev->temp_buffer[0x8]), 192 | res4x4, sizeof(res4x4)); 193 | (void)memcpy(&(p_dev->temp_buffer[0x020]), 194 | dss_4x4, sizeof(dss_4x4)); 195 | 196 | SwapBuffer(p_dev->temp_buffer, VL53L7CX_XTALK_BUFFER_SIZE); 197 | (void)memcpy(signal_grid, &(p_dev->temp_buffer[0x34]), 198 | sizeof(signal_grid)); 199 | 200 | for (j = 0; j < (int8_t)4; j++) { 201 | for (i = 0; i < (int8_t)4 ; i++) { 202 | signal_grid[i + (4 * j)] = 203 | (signal_grid[(2 * i) + (16 * j) + 0] 204 | + signal_grid[(2 * i) + (16 * j) + 1] 205 | + signal_grid[(2 * i) + (16 * j) + 8] 206 | + signal_grid[(2 * i) + (16 * j) + 9]) / (uint32_t)4; 207 | } 208 | } 209 | (void)memset(&signal_grid[0x10], 0, (uint32_t)192); 210 | (void)memcpy(&(p_dev->temp_buffer[0x34]), 211 | signal_grid, sizeof(signal_grid)); 212 | SwapBuffer(p_dev->temp_buffer, VL53L7CX_XTALK_BUFFER_SIZE); 213 | (void)memcpy(&(p_dev->temp_buffer[0x134]), 214 | profile_4x4, sizeof(profile_4x4)); 215 | (void)memset(&(p_dev->temp_buffer[0x078]), 0, 216 | (uint32_t)4 * sizeof(uint8_t)); 217 | } 218 | 219 | status |= WrMulti(&(p_dev->platform), 0x2cf8, 220 | p_dev->temp_buffer, VL53L7CX_XTALK_BUFFER_SIZE); 221 | status |= _vl53l7cx_poll_for_answer(4, 1, 222 | VL53L7CX_UI_CMD_STATUS, 0xff, 0x03); 223 | 224 | return status; 225 | } 226 | 227 | uint8_t VL53L7CX::vl53l7cx_is_alive(uint8_t *p_is_alive) 228 | { 229 | uint8_t status = VL53L7CX_STATUS_OK; 230 | uint8_t device_id, revision_id; 231 | 232 | status |= WrByte(&(p_dev->platform), 0x7fff, 0x00); 233 | status |= RdByte(&(p_dev->platform), 0, &device_id); 234 | status |= RdByte(&(p_dev->platform), 1, &revision_id); 235 | status |= WrByte(&(p_dev->platform), 0x7fff, 0x02); 236 | 237 | if ((device_id == (uint8_t)0xF0) && (revision_id == (uint8_t)0x02)) { 238 | *p_is_alive = 1; 239 | } else { 240 | *p_is_alive = 0; 241 | } 242 | 243 | return status; 244 | } 245 | 246 | uint8_t VL53L7CX::vl53l7cx_init() 247 | { 248 | uint8_t tmp, status = VL53L7CX_STATUS_OK; 249 | uint8_t pipe_ctrl[] = {VL53L7CX_NB_TARGET_PER_ZONE, 0x00, 0x01, 0x00}; 250 | uint32_t single_range = 0x01; 251 | 252 | p_dev->default_xtalk = (uint8_t *)VL53L7CX_DEFAULT_XTALK; 253 | p_dev->default_configuration = (uint8_t *)VL53L7CX_DEFAULT_CONFIGURATION; 254 | 255 | /* SW reboot sequence */ 256 | status |= WrByte(&(p_dev->platform), 0x7fff, 0x00); 257 | status |= WrByte(&(p_dev->platform), 0x0009, 0x04); 258 | status |= WrByte(&(p_dev->platform), 0x000F, 0x40); 259 | status |= WrByte(&(p_dev->platform), 0x000A, 0x03); 260 | status |= RdByte(&(p_dev->platform), 0x7FFF, &tmp); 261 | status |= WrByte(&(p_dev->platform), 0x000C, 0x01); 262 | 263 | status |= WrByte(&(p_dev->platform), 0x0101, 0x00); 264 | status |= WrByte(&(p_dev->platform), 0x0102, 0x00); 265 | status |= WrByte(&(p_dev->platform), 0x010A, 0x01); 266 | status |= WrByte(&(p_dev->platform), 0x4002, 0x01); 267 | status |= WrByte(&(p_dev->platform), 0x4002, 0x00); 268 | status |= WrByte(&(p_dev->platform), 0x010A, 0x03); 269 | status |= WrByte(&(p_dev->platform), 0x0103, 0x01); 270 | status |= WrByte(&(p_dev->platform), 0x000C, 0x00); 271 | status |= WrByte(&(p_dev->platform), 0x000F, 0x43); 272 | status |= WaitMs(&(p_dev->platform), 1); 273 | 274 | status |= WrByte(&(p_dev->platform), 0x000F, 0x40); 275 | status |= WrByte(&(p_dev->platform), 0x000A, 0x01); 276 | status |= WaitMs(&(p_dev->platform), 100); 277 | 278 | /* Wait for sensor booted (several ms required to get sensor ready ) */ 279 | status |= WrByte(&(p_dev->platform), 0x7fff, 0x00); 280 | status |= _vl53l7cx_poll_for_answer(1, 0, 0x06, 0xff, 1); 281 | if (status != (uint8_t)0) { 282 | goto exit; 283 | } 284 | 285 | status |= WrByte(&(p_dev->platform), 0x000E, 0x01); 286 | status |= WrByte(&(p_dev->platform), 0x7fff, 0x02); 287 | 288 | /* Enable FW access */ 289 | status |= WrByte(&(p_dev->platform), 0x03, 0x0D); 290 | status |= WrByte(&(p_dev->platform), 0x7fff, 0x01); 291 | status |= _vl53l7cx_poll_for_answer(1, 0, 0x21, 0x10, 0x10); 292 | status |= WrByte(&(p_dev->platform), 0x7fff, 0x00); 293 | 294 | /* Enable host access to GO1 */ 295 | status |= RdByte(&(p_dev->platform), 0x7fff, &tmp); 296 | status |= WrByte(&(p_dev->platform), 0x0C, 0x01); 297 | 298 | /* Power ON status */ 299 | status |= WrByte(&(p_dev->platform), 0x7fff, 0x00); 300 | status |= WrByte(&(p_dev->platform), 0x101, 0x00); 301 | status |= WrByte(&(p_dev->platform), 0x102, 0x00); 302 | status |= WrByte(&(p_dev->platform), 0x010A, 0x01); 303 | status |= WrByte(&(p_dev->platform), 0x4002, 0x01); 304 | status |= WrByte(&(p_dev->platform), 0x4002, 0x00); 305 | status |= WrByte(&(p_dev->platform), 0x010A, 0x03); 306 | status |= WrByte(&(p_dev->platform), 0x103, 0x01); 307 | status |= WrByte(&(p_dev->platform), 0x400F, 0x00); 308 | status |= WrByte(&(p_dev->platform), 0x21A, 0x43); 309 | status |= WrByte(&(p_dev->platform), 0x21A, 0x03); 310 | status |= WrByte(&(p_dev->platform), 0x21A, 0x01); 311 | status |= WrByte(&(p_dev->platform), 0x21A, 0x00); 312 | status |= WrByte(&(p_dev->platform), 0x219, 0x00); 313 | status |= WrByte(&(p_dev->platform), 0x21B, 0x00); 314 | 315 | /* Wake up MCU */ 316 | status |= WrByte(&(p_dev->platform), 0x7fff, 0x00); 317 | status |= RdByte(&(p_dev->platform), 0x7fff, &tmp); 318 | status |= WrByte(&(p_dev->platform), 0x0C, 0x00); 319 | status |= WrByte(&(p_dev->platform), 0x7fff, 0x01); 320 | status |= WrByte(&(p_dev->platform), 0x20, 0x07); 321 | status |= WrByte(&(p_dev->platform), 0x20, 0x06); 322 | 323 | /* Download FW into VL53L7CX */ 324 | status |= WrByte(&(p_dev->platform), 0x7fff, 0x09); 325 | status |= WrMulti(&(p_dev->platform), 0, 326 | (uint8_t *)&VL53L7CX_FIRMWARE[0], 0x8000); 327 | status |= WrByte(&(p_dev->platform), 0x7fff, 0x0a); 328 | status |= WrMulti(&(p_dev->platform), 0, 329 | (uint8_t *)&VL53L7CX_FIRMWARE[0x8000], 0x8000); 330 | status |= WrByte(&(p_dev->platform), 0x7fff, 0x0b); 331 | status |= WrMulti(&(p_dev->platform), 0, 332 | (uint8_t *)&VL53L7CX_FIRMWARE[0x10000], 0x5000); 333 | status |= WrByte(&(p_dev->platform), 0x7fff, 0x01); 334 | 335 | /* Check if FW correctly downloaded */ 336 | status |= WrByte(&(p_dev->platform), 0x7fff, 0x02); 337 | status |= WrByte(&(p_dev->platform), 0x03, 0x0D); 338 | status |= WrByte(&(p_dev->platform), 0x7fff, 0x01); 339 | status |= _vl53l7cx_poll_for_answer(1, 0, 0x21, 0x10, 0x10); 340 | if (status != (uint8_t)0) { 341 | goto exit; 342 | } 343 | 344 | status |= WrByte(&(p_dev->platform), 0x7fff, 0x00); 345 | status |= RdByte(&(p_dev->platform), 0x7fff, &tmp); 346 | status |= WrByte(&(p_dev->platform), 0x0C, 0x01); 347 | 348 | /* Reset MCU and wait boot */ 349 | status |= WrByte(&(p_dev->platform), 0x7FFF, 0x00); 350 | status |= WrByte(&(p_dev->platform), 0x114, 0x00); 351 | status |= WrByte(&(p_dev->platform), 0x115, 0x00); 352 | status |= WrByte(&(p_dev->platform), 0x116, 0x42); 353 | status |= WrByte(&(p_dev->platform), 0x117, 0x00); 354 | status |= WrByte(&(p_dev->platform), 0x0B, 0x00); 355 | status |= RdByte(&(p_dev->platform), 0x7fff, &tmp); 356 | status |= WrByte(&(p_dev->platform), 0x0C, 0x00); 357 | status |= WrByte(&(p_dev->platform), 0x0B, 0x01); 358 | status |= _vl53l7cx_poll_for_mcu_boot(); 359 | if (status != (uint8_t)0) { 360 | goto exit; 361 | } 362 | 363 | status |= WrByte(&(p_dev->platform), 0x7fff, 0x02); 364 | 365 | /* Get offset NVM data and store them into the offset buffer */ 366 | status |= WrMulti(&(p_dev->platform), 0x2fd8, 367 | (uint8_t *)VL53L7CX_GET_NVM_CMD, sizeof(VL53L7CX_GET_NVM_CMD)); 368 | status |= _vl53l7cx_poll_for_answer(4, 0, 369 | VL53L7CX_UI_CMD_STATUS, 0xff, 2); 370 | status |= RdMulti(&(p_dev->platform), VL53L7CX_UI_CMD_START, 371 | p_dev->temp_buffer, VL53L7CX_NVM_DATA_SIZE); 372 | (void)memcpy(p_dev->offset_data, p_dev->temp_buffer, 373 | VL53L7CX_OFFSET_BUFFER_SIZE); 374 | status |= _vl53l7cx_send_offset_data(VL53L7CX_RESOLUTION_4X4); 375 | 376 | /* Set default Xtalk shape. Send Xtalk to sensor */ 377 | (void)memcpy(p_dev->xtalk_data, (uint8_t *)VL53L7CX_DEFAULT_XTALK, 378 | VL53L7CX_XTALK_BUFFER_SIZE); 379 | status |= _vl53l7cx_send_xtalk_data(VL53L7CX_RESOLUTION_4X4); 380 | 381 | /* Send default configuration to VL53L7CX firmware */ 382 | status |= WrMulti(&(p_dev->platform), 0x2c34, 383 | p_dev->default_configuration, 384 | sizeof(VL53L7CX_DEFAULT_CONFIGURATION)); 385 | status |= _vl53l7cx_poll_for_answer(4, 1, 386 | VL53L7CX_UI_CMD_STATUS, 0xff, 0x03); 387 | 388 | status |= vl53l7cx_dci_write_data((uint8_t *)&pipe_ctrl, 389 | VL53L7CX_DCI_PIPE_CONTROL, (uint16_t)sizeof(pipe_ctrl)); 390 | #if VL53L7CX_NB_TARGET_PER_ZONE != 1 391 | tmp = VL53L7CX_NB_TARGET_PER_ZONE; 392 | status |= vl53l7cx_dci_replace_data(p_dev->temp_buffer, 393 | VL53L7CX_DCI_FW_NB_TARGET, 16, 394 | (uint8_t *)&tmp, 1, 0x0C); 395 | #endif 396 | 397 | status |= vl53l7cx_dci_write_data((uint8_t *)&single_range, 398 | VL53L7CX_DCI_SINGLE_RANGE, 399 | (uint16_t)sizeof(single_range)); 400 | exit: 401 | return status; 402 | } 403 | 404 | uint8_t VL53L7CX::vl53l7cx_set_i2c_address(uint16_t i2c_address) 405 | { 406 | uint8_t status = VL53L7CX_STATUS_OK; 407 | 408 | status |= WrByte(&(p_dev->platform), 0x7fff, 0x00); 409 | status |= WrByte(&(p_dev->platform), 0x4, (uint8_t)(i2c_address >> 1)); 410 | p_dev->platform.address = i2c_address; 411 | status |= WrByte(&(p_dev->platform), 0x7fff, 0x02); 412 | 413 | return status; 414 | } 415 | 416 | uint8_t VL53L7CX::vl53l7cx_get_power_mode(uint8_t *p_power_mode) 417 | { 418 | uint8_t tmp, status = VL53L7CX_STATUS_OK; 419 | 420 | status |= WrByte(&(p_dev->platform), 0x7FFF, 0x00); 421 | status |= RdByte(&(p_dev->platform), 0x009, &tmp); 422 | 423 | switch (tmp) { 424 | case 0x4: 425 | *p_power_mode = VL53L7CX_POWER_MODE_WAKEUP; 426 | break; 427 | case 0x2: 428 | *p_power_mode = VL53L7CX_POWER_MODE_SLEEP; 429 | 430 | break; 431 | default: 432 | *p_power_mode = 0; 433 | status = VL53L7CX_STATUS_ERROR; 434 | break; 435 | } 436 | 437 | status |= WrByte(&(p_dev->platform), 0x7FFF, 0x02); 438 | 439 | return status; 440 | } 441 | 442 | uint8_t VL53L7CX::vl53l7cx_set_power_mode(uint8_t power_mode) 443 | { 444 | uint8_t current_power_mode, status = VL53L7CX_STATUS_OK; 445 | 446 | status |= vl53l7cx_get_power_mode(¤t_power_mode); 447 | if (power_mode != current_power_mode) { 448 | switch (power_mode) { 449 | case VL53L7CX_POWER_MODE_WAKEUP: 450 | status |= WrByte(&(p_dev->platform), 0x7FFF, 0x00); 451 | status |= WrByte(&(p_dev->platform), 0x09, 0x04); 452 | status |= _vl53l7cx_poll_for_answer( 453 | 1, 0, 0x06, 0x01, 1); 454 | break; 455 | 456 | case VL53L7CX_POWER_MODE_SLEEP: 457 | status |= WrByte(&(p_dev->platform), 0x7FFF, 0x00); 458 | status |= WrByte(&(p_dev->platform), 0x09, 0x02); 459 | status |= _vl53l7cx_poll_for_answer( 460 | 1, 0, 0x06, 0x01, 0); 461 | break; 462 | 463 | default: 464 | status = VL53L7CX_STATUS_ERROR; 465 | break; 466 | } 467 | status |= WrByte(&(p_dev->platform), 0x7FFF, 0x02); 468 | } 469 | 470 | return status; 471 | } 472 | 473 | uint8_t VL53L7CX::vl53l7cx_start_ranging() 474 | { 475 | uint8_t resolution, status = VL53L7CX_STATUS_OK; 476 | uint16_t tmp; 477 | uint32_t i; 478 | uint32_t header_config[2] = {0, 0}; 479 | 480 | union Block_header *bh_ptr; 481 | uint8_t cmd[] = {0x00, 0x03, 0x00, 0x00}; 482 | 483 | status |= vl53l7cx_get_resolution(&resolution); 484 | p_dev->data_read_size = 0; 485 | p_dev->streamcount = 255; 486 | 487 | /* Enable mandatory output (meta and common data) */ 488 | uint32_t output_bh_enable[] = { 489 | 0x00000007U, 490 | 0x00000000U, 491 | 0x00000000U, 492 | 0xC0000000U 493 | }; 494 | 495 | /* Send addresses of possible output */ 496 | uint32_t output[] = {VL53L7CX_START_BH, 497 | VL53L7CX_METADATA_BH, 498 | VL53L7CX_COMMONDATA_BH, 499 | VL53L7CX_AMBIENT_RATE_BH, 500 | VL53L7CX_SPAD_COUNT_BH, 501 | VL53L7CX_NB_TARGET_DETECTED_BH, 502 | VL53L7CX_SIGNAL_RATE_BH, 503 | VL53L7CX_RANGE_SIGMA_MM_BH, 504 | VL53L7CX_DISTANCE_BH, 505 | VL53L7CX_REFLECTANCE_BH, 506 | VL53L7CX_TARGET_STATUS_BH, 507 | VL53L7CX_MOTION_DETECT_BH 508 | }; 509 | 510 | /* Enable selected outputs in the 'platform.h' file */ 511 | #ifndef VL53L7CX_DISABLE_AMBIENT_PER_SPAD 512 | output_bh_enable[0] += (uint32_t)8; 513 | #endif 514 | #ifndef VL53L7CX_DISABLE_NB_SPADS_ENABLED 515 | output_bh_enable[0] += (uint32_t)16; 516 | #endif 517 | #ifndef VL53L7CX_DISABLE_NB_TARGET_DETECTED 518 | output_bh_enable[0] += (uint32_t)32; 519 | #endif 520 | #ifndef VL53L7CX_DISABLE_SIGNAL_PER_SPAD 521 | output_bh_enable[0] += (uint32_t)64; 522 | #endif 523 | #ifndef VL53L7CX_DISABLE_RANGE_SIGMA_MM 524 | output_bh_enable[0] += (uint32_t)128; 525 | #endif 526 | #ifndef VL53L7CX_DISABLE_DISTANCE_MM 527 | output_bh_enable[0] += (uint32_t)256; 528 | #endif 529 | #ifndef VL53L7CX_DISABLE_REFLECTANCE_PERCENT 530 | output_bh_enable[0] += (uint32_t)512; 531 | #endif 532 | #ifndef VL53L7CX_DISABLE_TARGET_STATUS 533 | output_bh_enable[0] += (uint32_t)1024; 534 | #endif 535 | #ifndef VL53L7CX_DISABLE_MOTION_INDICATOR 536 | output_bh_enable[0] += (uint32_t)2048; 537 | #endif 538 | 539 | /* Update data size */ 540 | for (i = 0; i < (uint32_t)(sizeof(output) / sizeof(uint32_t)); i++) { 541 | if ((output[i] == (uint8_t)0) 542 | || ((output_bh_enable[i / (uint32_t)32] 543 | & ((uint32_t)1 << (i % (uint32_t)32))) == (uint32_t)0)) { 544 | continue; 545 | } 546 | 547 | bh_ptr = (union Block_header *) & (output[i]); 548 | if (((uint8_t)bh_ptr->type >= (uint8_t)0x1) 549 | && ((uint8_t)bh_ptr->type < (uint8_t)0x0d)) { 550 | if ((bh_ptr->idx >= (uint16_t)0x54d0) 551 | && (bh_ptr->idx < (uint16_t)(0x54d0 + 960))) { 552 | bh_ptr->size = resolution; 553 | } else { 554 | bh_ptr->size = (uint16_t)((uint16_t)resolution 555 | * (uint16_t)VL53L7CX_NB_TARGET_PER_ZONE); 556 | } 557 | p_dev->data_read_size += bh_ptr->type * bh_ptr->size; 558 | } else { 559 | p_dev->data_read_size += bh_ptr->size; 560 | } 561 | p_dev->data_read_size += (uint32_t)4; 562 | } 563 | p_dev->data_read_size += (uint32_t)24; 564 | 565 | status |= vl53l7cx_dci_write_data( 566 | (uint8_t *) & (output), VL53L7CX_DCI_OUTPUT_LIST, 567 | (uint16_t)sizeof(output)); 568 | 569 | header_config[0] = p_dev->data_read_size; 570 | header_config[1] = i + (uint32_t)1; 571 | 572 | status |= vl53l7cx_dci_write_data( 573 | (uint8_t *) & (header_config), VL53L7CX_DCI_OUTPUT_CONFIG, 574 | (uint16_t)sizeof(header_config)); 575 | 576 | status |= vl53l7cx_dci_write_data( 577 | (uint8_t *) & (output_bh_enable), VL53L7CX_DCI_OUTPUT_ENABLES, 578 | (uint16_t)sizeof(output_bh_enable)); 579 | 580 | /* Start xshut bypass (interrupt mode) */ 581 | status |= WrByte(&(p_dev->platform), 0x7fff, 0x00); 582 | status |= WrByte(&(p_dev->platform), 0x09, 0x05); 583 | status |= WrByte(&(p_dev->platform), 0x7fff, 0x02); 584 | 585 | /* Start ranging session */ 586 | status |= WrMulti(&(p_dev->platform), VL53L7CX_UI_CMD_END - 587 | (uint16_t)(4 - 1), (uint8_t *)cmd, sizeof(cmd)); 588 | status |= _vl53l7cx_poll_for_answer(4, 1, 589 | VL53L7CX_UI_CMD_STATUS, 0xff, 0x03); 590 | 591 | /* Read ui range data content and compare if data size is the correct one */ 592 | status |= vl53l7cx_dci_read_data( 593 | (uint8_t *)p_dev->temp_buffer, 0x5440, 12); 594 | (void)memcpy(&tmp, &(p_dev->temp_buffer[0x8]), sizeof(tmp)); 595 | if (tmp != p_dev->data_read_size) { 596 | status |= VL53L7CX_STATUS_ERROR; 597 | } 598 | 599 | return status; 600 | } 601 | 602 | uint8_t VL53L7CX::vl53l7cx_stop_ranging() 603 | { 604 | uint8_t tmp = 0, status = VL53L7CX_STATUS_OK; 605 | uint16_t timeout = 0; 606 | uint32_t auto_stop_flag = 0; 607 | 608 | status |= RdMulti(&(p_dev->platform), 609 | 0x2FFC, (uint8_t *)&auto_stop_flag, 4); 610 | if (auto_stop_flag != (uint32_t)0x4FF) { 611 | status |= WrByte(&(p_dev->platform), 0x7fff, 0x00); 612 | 613 | /* Provoke MCU stop */ 614 | status |= WrByte(&(p_dev->platform), 0x15, 0x16); 615 | status |= WrByte(&(p_dev->platform), 0x14, 0x01); 616 | 617 | /* Poll for G02 status 0 MCU stop */ 618 | while (((tmp & (uint8_t)0x80) >> 7) == (uint8_t)0x00) { 619 | status |= RdByte(&(p_dev->platform), 0x6, &tmp); 620 | status |= WaitMs(&(p_dev->platform), 10); 621 | timeout++; /* Timeout reached after 5 seconds */ 622 | 623 | if (timeout > (uint16_t)500) { 624 | status |= tmp; 625 | break; 626 | } 627 | } 628 | } 629 | 630 | /* Check GO2 status 1 if status is still OK */ 631 | status |= RdByte(&(p_dev->platform), 0x6, &tmp); 632 | if ((tmp & (uint8_t)0x80) != (uint8_t)0) { 633 | status |= RdByte(&(p_dev->platform), 0x7, &tmp); 634 | if ((tmp != (uint8_t)0x84) && (tmp != (uint8_t)0x85)) { 635 | status |= tmp; 636 | } 637 | } 638 | 639 | /* Undo MCU stop */ 640 | status |= WrByte(&(p_dev->platform), 0x7fff, 0x00); 641 | status |= WrByte(&(p_dev->platform), 0x14, 0x00); 642 | status |= WrByte(&(p_dev->platform), 0x15, 0x00); 643 | 644 | /* Stop xshut bypass */ 645 | status |= WrByte(&(p_dev->platform), 0x09, 0x04); 646 | status |= WrByte(&(p_dev->platform), 0x7fff, 0x02); 647 | 648 | return status; 649 | } 650 | 651 | uint8_t VL53L7CX::vl53l7cx_check_data_ready(uint8_t *p_isReady) 652 | { 653 | uint8_t status = VL53L7CX_STATUS_OK; 654 | 655 | status |= RdMulti(&(p_dev->platform), 0x0, p_dev->temp_buffer, 4); 656 | 657 | if ((p_dev->temp_buffer[0] != p_dev->streamcount) 658 | && (p_dev->temp_buffer[0] != (uint8_t)255) 659 | && (p_dev->temp_buffer[1] == (uint8_t)0x5) 660 | && ((p_dev->temp_buffer[2] & (uint8_t)0x5) == (uint8_t)0x5) 661 | && ((p_dev->temp_buffer[3] & (uint8_t)0x10) == (uint8_t)0x10) 662 | ) { 663 | *p_isReady = (uint8_t)1; 664 | p_dev->streamcount = p_dev->temp_buffer[0]; 665 | } else { 666 | if ((p_dev->temp_buffer[3] & (uint8_t)0x80) != (uint8_t)0) { 667 | status |= p_dev->temp_buffer[2]; /* Return GO2 error status */ 668 | } 669 | 670 | *p_isReady = 0; 671 | } 672 | 673 | return status; 674 | } 675 | 676 | uint8_t VL53L7CX::vl53l7cx_get_ranging_data(VL53L7CX_ResultsData *p_results) 677 | { 678 | uint8_t status = VL53L7CX_STATUS_OK; 679 | uint16_t header_id, footer_id; 680 | union Block_header *bh_ptr; 681 | uint32_t i, j, msize; 682 | status |= RdMulti(&(p_dev->platform), 0x0, 683 | p_dev->temp_buffer, p_dev->data_read_size); 684 | p_dev->streamcount = p_dev->temp_buffer[0]; 685 | SwapBuffer(p_dev->temp_buffer, (uint16_t)p_dev->data_read_size); 686 | 687 | /* Start conversion at position 16 to avoid headers */ 688 | for (i = 16U; i < (uint32_t)p_dev->data_read_size; i += 4U) { 689 | bh_ptr = (union Block_header *) & (p_dev->temp_buffer[i]); 690 | if ((bh_ptr->type > 0x1U) 691 | && (bh_ptr->type < 0xdU)) { 692 | msize = bh_ptr->type * bh_ptr->size; 693 | } else { 694 | msize = bh_ptr->size; 695 | } 696 | 697 | switch (bh_ptr->idx) { 698 | case VL53L7CX_METADATA_IDX: 699 | p_results->silicon_temp_degc = 700 | (int8_t)p_dev->temp_buffer[i + (uint32_t)12]; 701 | break; 702 | 703 | #ifndef VL53L7CX_DISABLE_AMBIENT_PER_SPAD 704 | case VL53L7CX_AMBIENT_RATE_IDX: 705 | (void)memcpy(p_results->ambient_per_spad, 706 | &(p_dev->temp_buffer[i + (uint32_t)4]), msize); 707 | break; 708 | #endif 709 | #ifndef VL53L7CX_DISABLE_NB_SPADS_ENABLED 710 | case VL53L7CX_SPAD_COUNT_IDX: 711 | (void)memcpy(p_results->nb_spads_enabled, 712 | &(p_dev->temp_buffer[i + (uint32_t)4]), msize); 713 | break; 714 | #endif 715 | #ifndef VL53L7CX_DISABLE_NB_TARGET_DETECTED 716 | case VL53L7CX_NB_TARGET_DETECTED_IDX: 717 | (void)memcpy(p_results->nb_target_detected, 718 | &(p_dev->temp_buffer[i + (uint32_t)4]), msize); 719 | break; 720 | #endif 721 | #ifndef VL53L7CX_DISABLE_SIGNAL_PER_SPAD 722 | case VL53L7CX_SIGNAL_RATE_IDX: 723 | (void)memcpy(p_results->signal_per_spad, 724 | &(p_dev->temp_buffer[i + (uint32_t)4]), msize); 725 | break; 726 | #endif 727 | #ifndef VL53L7CX_DISABLE_RANGE_SIGMA_MM 728 | case VL53L7CX_RANGE_SIGMA_MM_IDX: 729 | (void)memcpy(p_results->range_sigma_mm, 730 | &(p_dev->temp_buffer[i + (uint32_t)4]), msize); 731 | break; 732 | #endif 733 | #ifndef VL53L7CX_DISABLE_DISTANCE_MM 734 | case VL53L7CX_DISTANCE_IDX: 735 | (void)memcpy(p_results->distance_mm, 736 | &(p_dev->temp_buffer[i + (uint32_t)4]), msize); 737 | break; 738 | #endif 739 | #ifndef VL53L7CX_DISABLE_REFLECTANCE_PERCENT 740 | case VL53L7CX_REFLECTANCE_EST_PC_IDX: 741 | (void)memcpy(p_results->reflectance, 742 | &(p_dev->temp_buffer[i + (uint32_t)4]), msize); 743 | break; 744 | #endif 745 | #ifndef VL53L7CX_DISABLE_TARGET_STATUS 746 | case VL53L7CX_TARGET_STATUS_IDX: 747 | (void)memcpy(p_results->target_status, 748 | &(p_dev->temp_buffer[i + (uint32_t)4]), msize); 749 | break; 750 | #endif 751 | #ifndef VL53L7CX_DISABLE_MOTION_INDICATOR 752 | case VL53L7CX_MOTION_DETEC_IDX: 753 | (void)memcpy(&p_results->motion_indicator, 754 | &(p_dev->temp_buffer[i + (uint32_t)4]), msize); 755 | break; 756 | #endif 757 | default: 758 | break; 759 | } 760 | i += msize; 761 | } 762 | 763 | #ifndef VL53L7CX_USE_RAW_FORMAT 764 | 765 | /* Convert data into their real format */ 766 | #ifndef VL53L7CX_DISABLE_AMBIENT_PER_SPAD 767 | for (i = 0; i < (uint32_t)VL53L7CX_RESOLUTION_8X8; i++) { 768 | p_results->ambient_per_spad[i] /= (uint32_t)2048; 769 | } 770 | #endif 771 | 772 | for (i = 0; i < (uint32_t)(VL53L7CX_RESOLUTION_8X8 773 | *VL53L7CX_NB_TARGET_PER_ZONE); i++) { 774 | #ifndef VL53L7CX_DISABLE_DISTANCE_MM 775 | p_results->distance_mm[i] /= 4; 776 | if (p_results->distance_mm[i] < 0) { 777 | p_results->distance_mm[i] = 0; 778 | } 779 | #endif 780 | #ifndef VL53L7CX_DISABLE_REFLECTANCE_PERCENT 781 | p_results->reflectance[i] /= (uint8_t)2; 782 | #endif 783 | #ifndef VL53L7CX_DISABLE_RANGE_SIGMA_MM 784 | p_results->range_sigma_mm[i] /= (uint16_t)128; 785 | #endif 786 | #ifndef VL53L7CX_DISABLE_SIGNAL_PER_SPAD 787 | p_results->signal_per_spad[i] /= (uint32_t)2048; 788 | #endif 789 | } 790 | 791 | /* Set target status to 255 if no target is detected for this zone */ 792 | #ifndef VL53L7CX_DISABLE_NB_TARGET_DETECTED 793 | for (i = 0; i < (uint32_t)VL53L7CX_RESOLUTION_8X8; i++) { 794 | if (p_results->nb_target_detected[i] == (uint8_t)0) { 795 | for (j = 0; j < (uint32_t) 796 | VL53L7CX_NB_TARGET_PER_ZONE; j++) { 797 | #ifndef VL53L7CX_DISABLE_TARGET_STATUS 798 | p_results->target_status 799 | [((uint32_t)VL53L7CX_NB_TARGET_PER_ZONE 800 | * (uint32_t)i) + j] = (uint8_t)255; 801 | #endif 802 | } 803 | } 804 | } 805 | #endif 806 | 807 | #ifndef VL53L7CX_DISABLE_MOTION_INDICATOR 808 | for (i = 0; i < (uint32_t)32; i++) { 809 | p_results->motion_indicator.motion[i] /= (uint32_t)65535; 810 | } 811 | #endif 812 | 813 | #endif 814 | 815 | /* Check if footer id and header id are matching. This allows to detect 816 | * corrupted frames */ 817 | header_id = ((uint16_t)(p_dev->temp_buffer[0x8]) << 8) & 0xFF00U; 818 | header_id |= ((uint16_t)(p_dev->temp_buffer[0x9])) & 0x00FFU; 819 | 820 | footer_id = ((uint16_t)(p_dev->temp_buffer[p_dev->data_read_size 821 | - (uint32_t)4]) << 8) & 0xFF00U; 822 | footer_id |= ((uint16_t)(p_dev->temp_buffer[p_dev->data_read_size 823 | - (uint32_t)3])) & 0xFFU; 824 | if (header_id != footer_id) { 825 | status |= VL53L7CX_STATUS_CORRUPTED_FRAME; 826 | } 827 | 828 | return status; 829 | } 830 | 831 | uint8_t VL53L7CX::vl53l7cx_get_resolution(uint8_t *p_resolution) 832 | { 833 | uint8_t status = VL53L7CX_STATUS_OK; 834 | 835 | status |= vl53l7cx_dci_read_data(p_dev->temp_buffer, 836 | VL53L7CX_DCI_ZONE_CONFIG, 8); 837 | *p_resolution = p_dev->temp_buffer[0x00] * p_dev->temp_buffer[0x01]; 838 | 839 | return status; 840 | } 841 | 842 | uint8_t VL53L7CX::vl53l7cx_set_resolution(uint8_t resolution) 843 | { 844 | uint8_t status = VL53L7CX_STATUS_OK; 845 | 846 | switch (resolution) { 847 | case VL53L7CX_RESOLUTION_4X4: 848 | status |= vl53l7cx_dci_read_data( 849 | p_dev->temp_buffer, 850 | VL53L7CX_DCI_DSS_CONFIG, 16); 851 | p_dev->temp_buffer[0x04] = 64; 852 | p_dev->temp_buffer[0x06] = 64; 853 | p_dev->temp_buffer[0x09] = 4; 854 | status |= vl53l7cx_dci_write_data( 855 | p_dev->temp_buffer, 856 | VL53L7CX_DCI_DSS_CONFIG, 16); 857 | 858 | status |= vl53l7cx_dci_read_data( 859 | p_dev->temp_buffer, 860 | VL53L7CX_DCI_ZONE_CONFIG, 8); 861 | p_dev->temp_buffer[0x00] = 4; 862 | p_dev->temp_buffer[0x01] = 4; 863 | p_dev->temp_buffer[0x04] = 8; 864 | p_dev->temp_buffer[0x05] = 8; 865 | status |= vl53l7cx_dci_write_data( 866 | p_dev->temp_buffer, 867 | VL53L7CX_DCI_ZONE_CONFIG, 8); 868 | break; 869 | 870 | case VL53L7CX_RESOLUTION_8X8: 871 | status |= vl53l7cx_dci_read_data( 872 | p_dev->temp_buffer, 873 | VL53L7CX_DCI_DSS_CONFIG, 16); 874 | p_dev->temp_buffer[0x04] = 16; 875 | p_dev->temp_buffer[0x06] = 16; 876 | p_dev->temp_buffer[0x09] = 1; 877 | status |= vl53l7cx_dci_write_data( 878 | p_dev->temp_buffer, 879 | VL53L7CX_DCI_DSS_CONFIG, 16); 880 | 881 | status |= vl53l7cx_dci_read_data( 882 | p_dev->temp_buffer, 883 | VL53L7CX_DCI_ZONE_CONFIG, 8); 884 | p_dev->temp_buffer[0x00] = 8; 885 | p_dev->temp_buffer[0x01] = 8; 886 | p_dev->temp_buffer[0x04] = 4; 887 | p_dev->temp_buffer[0x05] = 4; 888 | status |= vl53l7cx_dci_write_data( 889 | p_dev->temp_buffer, 890 | VL53L7CX_DCI_ZONE_CONFIG, 8); 891 | 892 | break; 893 | 894 | default: 895 | status = VL53L7CX_STATUS_INVALID_PARAM; 896 | break; 897 | } 898 | 899 | status |= _vl53l7cx_send_offset_data(resolution); 900 | status |= _vl53l7cx_send_xtalk_data(resolution); 901 | 902 | return status; 903 | } 904 | 905 | uint8_t VL53L7CX::vl53l7cx_get_ranging_frequency_hz(uint8_t *p_frequency_hz) 906 | { 907 | uint8_t status = VL53L7CX_STATUS_OK; 908 | 909 | status |= vl53l7cx_dci_read_data((uint8_t *)p_dev->temp_buffer, 910 | VL53L7CX_DCI_FREQ_HZ, 4); 911 | *p_frequency_hz = p_dev->temp_buffer[0x01]; 912 | 913 | return status; 914 | } 915 | 916 | uint8_t VL53L7CX::vl53l7cx_set_ranging_frequency_hz(uint8_t frequency_hz) 917 | { 918 | uint8_t status = VL53L7CX_STATUS_OK; 919 | 920 | status |= vl53l7cx_dci_replace_data(p_dev->temp_buffer, 921 | VL53L7CX_DCI_FREQ_HZ, 4, 922 | (uint8_t *)&frequency_hz, 1, 0x01); 923 | 924 | return status; 925 | } 926 | 927 | uint8_t VL53L7CX::vl53l7cx_get_integration_time_ms(uint32_t *p_time_ms) 928 | { 929 | uint8_t status = VL53L7CX_STATUS_OK; 930 | 931 | status |= vl53l7cx_dci_read_data((uint8_t *)p_dev->temp_buffer, 932 | VL53L7CX_DCI_INT_TIME, 20); 933 | 934 | (void)memcpy(p_time_ms, &(p_dev->temp_buffer[0x0]), 4); 935 | *p_time_ms /= (uint32_t)1000; 936 | 937 | return status; 938 | } 939 | 940 | uint8_t VL53L7CX::vl53l7cx_set_integration_time_ms(uint32_t integration_time_ms) 941 | { 942 | uint8_t status = VL53L7CX_STATUS_OK; 943 | uint32_t integration = integration_time_ms; 944 | 945 | /* Integration time must be between 2ms and 1000ms */ 946 | if ((integration < (uint32_t)2) 947 | || (integration > (uint32_t)1000)) { 948 | status |= VL53L7CX_STATUS_INVALID_PARAM; 949 | } else { 950 | integration *= (uint32_t)1000; 951 | 952 | status |= vl53l7cx_dci_replace_data(p_dev->temp_buffer, 953 | VL53L7CX_DCI_INT_TIME, 20, 954 | (uint8_t *)&integration, 4, 0x00); 955 | } 956 | 957 | return status; 958 | } 959 | 960 | uint8_t VL53L7CX::vl53l7cx_get_sharpener_percent(uint8_t *p_sharpener_percent) 961 | { 962 | uint8_t status = VL53L7CX_STATUS_OK; 963 | 964 | status |= vl53l7cx_dci_read_data(p_dev->temp_buffer, 965 | VL53L7CX_DCI_SHARPENER, 16); 966 | 967 | *p_sharpener_percent = (p_dev->temp_buffer[0xD] 968 | * (uint8_t)100) / (uint8_t)255; 969 | 970 | return status; 971 | } 972 | 973 | uint8_t VL53L7CX::vl53l7cx_set_sharpener_percent(uint8_t sharpener_percent) 974 | { 975 | uint8_t status = VL53L7CX_STATUS_OK; 976 | uint8_t sharpener; 977 | 978 | if (sharpener_percent >= (uint8_t)100) { 979 | status |= VL53L7CX_STATUS_INVALID_PARAM; 980 | } else { 981 | sharpener = (sharpener_percent * (uint8_t)255) / (uint8_t)100; 982 | status |= vl53l7cx_dci_replace_data(p_dev->temp_buffer, 983 | VL53L7CX_DCI_SHARPENER, 16, 984 | (uint8_t *)&sharpener, 1, 0xD); 985 | } 986 | 987 | return status; 988 | } 989 | 990 | uint8_t VL53L7CX::vl53l7cx_get_target_order(uint8_t *p_target_order) 991 | { 992 | uint8_t status = VL53L7CX_STATUS_OK; 993 | 994 | status |= vl53l7cx_dci_read_data((uint8_t *)p_dev->temp_buffer, 995 | VL53L7CX_DCI_TARGET_ORDER, 4); 996 | *p_target_order = (uint8_t)p_dev->temp_buffer[0x0]; 997 | 998 | return status; 999 | } 1000 | 1001 | uint8_t VL53L7CX::vl53l7cx_set_target_order(uint8_t target_order) 1002 | { 1003 | uint8_t status = VL53L7CX_STATUS_OK; 1004 | 1005 | if ((target_order == (uint8_t)VL53L7CX_TARGET_ORDER_CLOSEST) 1006 | || (target_order == (uint8_t)VL53L7CX_TARGET_ORDER_STRONGEST)) { 1007 | status |= vl53l7cx_dci_replace_data(p_dev->temp_buffer, 1008 | VL53L7CX_DCI_TARGET_ORDER, 4, 1009 | (uint8_t *)&target_order, 1, 0x0); 1010 | } else { 1011 | status |= VL53L7CX_STATUS_INVALID_PARAM; 1012 | } 1013 | 1014 | return status; 1015 | } 1016 | 1017 | uint8_t VL53L7CX::vl53l7cx_get_ranging_mode(uint8_t *p_ranging_mode) 1018 | { 1019 | uint8_t status = VL53L7CX_STATUS_OK; 1020 | 1021 | status |= vl53l7cx_dci_read_data(p_dev->temp_buffer, 1022 | VL53L7CX_DCI_RANGING_MODE, 8); 1023 | 1024 | if (p_dev->temp_buffer[0x01] == (uint8_t)0x1) { 1025 | *p_ranging_mode = VL53L7CX_RANGING_MODE_CONTINUOUS; 1026 | } else { 1027 | *p_ranging_mode = VL53L7CX_RANGING_MODE_AUTONOMOUS; 1028 | } 1029 | 1030 | return status; 1031 | } 1032 | 1033 | uint8_t VL53L7CX::vl53l7cx_set_ranging_mode(uint8_t ranging_mode) 1034 | { 1035 | uint8_t status = VL53L7CX_STATUS_OK; 1036 | uint32_t single_range = 0x00; 1037 | 1038 | status |= vl53l7cx_dci_read_data(p_dev->temp_buffer, 1039 | VL53L7CX_DCI_RANGING_MODE, 8); 1040 | 1041 | switch (ranging_mode) { 1042 | case VL53L7CX_RANGING_MODE_CONTINUOUS: 1043 | p_dev->temp_buffer[0x01] = 0x1; 1044 | p_dev->temp_buffer[0x03] = 0x3; 1045 | single_range = 0x00; 1046 | break; 1047 | 1048 | case VL53L7CX_RANGING_MODE_AUTONOMOUS: 1049 | p_dev->temp_buffer[0x01] = 0x3; 1050 | p_dev->temp_buffer[0x03] = 0x2; 1051 | single_range = 0x01; 1052 | break; 1053 | 1054 | default: 1055 | status = VL53L7CX_STATUS_INVALID_PARAM; 1056 | break; 1057 | } 1058 | 1059 | status |= vl53l7cx_dci_write_data(p_dev->temp_buffer, 1060 | VL53L7CX_DCI_RANGING_MODE, (uint16_t)8); 1061 | 1062 | status |= vl53l7cx_dci_write_data((uint8_t *)&single_range, 1063 | VL53L7CX_DCI_SINGLE_RANGE, 1064 | (uint16_t)sizeof(single_range)); 1065 | 1066 | return status; 1067 | } 1068 | 1069 | uint8_t VL53L7CX::vl53l7cx_dci_read_data( 1070 | uint8_t *data, 1071 | uint32_t index, 1072 | uint16_t data_size) 1073 | { 1074 | int16_t i; 1075 | uint8_t status = VL53L7CX_STATUS_OK; 1076 | uint32_t rd_size = (uint32_t) data_size + (uint32_t)12; 1077 | uint8_t cmd[] = {0x00, 0x00, 0x00, 0x00, 1078 | 0x00, 0x00, 0x00, 0x0f, 1079 | 0x00, 0x02, 0x00, 0x08 1080 | }; 1081 | 1082 | /* Check if tmp buffer is large enough */ 1083 | if ((data_size + (uint16_t)12) > (uint16_t)VL53L7CX_TEMPORARY_BUFFER_SIZE) { 1084 | status |= VL53L7CX_STATUS_ERROR; 1085 | } else { 1086 | cmd[0] = (uint8_t)(index >> 8); 1087 | cmd[1] = (uint8_t)(index & (uint32_t)0xff); 1088 | cmd[2] = (uint8_t)((data_size & (uint16_t)0xff0) >> 4); 1089 | cmd[3] = (uint8_t)((data_size & (uint16_t)0xf) << 4); 1090 | 1091 | /* Request data reading from FW */ 1092 | status |= WrMulti(&(p_dev->platform), 1093 | (VL53L7CX_UI_CMD_END - (uint16_t)11), cmd, sizeof(cmd)); 1094 | status |= _vl53l7cx_poll_for_answer(4, 1, 1095 | VL53L7CX_UI_CMD_STATUS, 1096 | 0xff, 0x03); 1097 | 1098 | /* Read new data sent (4 bytes header + data_size + 8 bytes footer) */ 1099 | status |= RdMulti(&(p_dev->platform), VL53L7CX_UI_CMD_START, 1100 | p_dev->temp_buffer, rd_size); 1101 | SwapBuffer(p_dev->temp_buffer, data_size + (uint16_t)12); 1102 | 1103 | /* Copy data from FW into input structure (-4 bytes to remove header) */ 1104 | for (i = 0 ; i < (int16_t)data_size; i++) { 1105 | data[i] = p_dev->temp_buffer[i + 4]; 1106 | } 1107 | } 1108 | 1109 | return status; 1110 | } 1111 | 1112 | uint8_t VL53L7CX::vl53l7cx_dci_write_data( 1113 | uint8_t *data, 1114 | uint32_t index, 1115 | uint16_t data_size) 1116 | { 1117 | uint8_t status = VL53L7CX_STATUS_OK; 1118 | int16_t i; 1119 | 1120 | uint8_t headers[] = {0x00, 0x00, 0x00, 0x00}; 1121 | uint8_t footer[] = {0x00, 0x00, 0x00, 0x0f, 0x05, 0x01, 1122 | (uint8_t)((data_size + (uint16_t)8) >> 8), 1123 | (uint8_t)((data_size + (uint16_t)8) & (uint8_t)0xFF) 1124 | }; 1125 | 1126 | uint16_t address = (uint16_t)VL53L7CX_UI_CMD_END - 1127 | (data_size + (uint16_t)12) + (uint16_t)1; 1128 | 1129 | /* Check if cmd buffer is large enough */ 1130 | if ((data_size + (uint16_t)12) 1131 | > (uint16_t)VL53L7CX_TEMPORARY_BUFFER_SIZE) { 1132 | status |= VL53L7CX_STATUS_ERROR; 1133 | } else { 1134 | headers[0] = (uint8_t)(index >> 8); 1135 | headers[1] = (uint8_t)(index & (uint32_t)0xff); 1136 | headers[2] = (uint8_t)(((data_size & (uint16_t)0xff0) >> 4)); 1137 | headers[3] = (uint8_t)((data_size & (uint16_t)0xf) << 4); 1138 | 1139 | /* Copy data from structure to FW format (+4 bytes to add header) */ 1140 | SwapBuffer(data, data_size); 1141 | for (i = (int16_t)data_size - (int16_t)1 ; i >= 0; i--) { 1142 | p_dev->temp_buffer[i + 4] = data[i]; 1143 | } 1144 | 1145 | /* Add headers and footer */ 1146 | (void)memcpy(&p_dev->temp_buffer[0], headers, sizeof(headers)); 1147 | (void)memcpy(&p_dev->temp_buffer[data_size + (uint16_t)4], 1148 | footer, sizeof(footer)); 1149 | 1150 | /* Send data to FW */ 1151 | status |= WrMulti(&(p_dev->platform), address, 1152 | p_dev->temp_buffer, 1153 | (uint32_t)((uint32_t)data_size + (uint32_t)12)); 1154 | status |= _vl53l7cx_poll_for_answer(4, 1, 1155 | VL53L7CX_UI_CMD_STATUS, 0xff, 0x03); 1156 | 1157 | SwapBuffer(data, data_size); 1158 | } 1159 | 1160 | return status; 1161 | } 1162 | 1163 | uint8_t VL53L7CX::vl53l7cx_dci_replace_data( 1164 | uint8_t *data, 1165 | uint32_t index, 1166 | uint16_t data_size, 1167 | uint8_t *new_data, 1168 | uint16_t new_data_size, 1169 | uint16_t new_data_pos) 1170 | { 1171 | uint8_t status = VL53L7CX_STATUS_OK; 1172 | 1173 | status |= vl53l7cx_dci_read_data(data, index, data_size); 1174 | (void)memcpy(&(data[new_data_pos]), new_data, new_data_size); 1175 | status |= vl53l7cx_dci_write_data(data, index, data_size); 1176 | 1177 | return status; 1178 | } 1179 | -------------------------------------------------------------------------------- /src/vl53l7cx_api.h: -------------------------------------------------------------------------------- 1 | /** 2 | ****************************************************************************** 3 | * @file vl53l7cx_api.h 4 | * @author STMicroelectronics 5 | * @version V1.0.0 6 | * @date 13 January 2023 7 | * @brief Header file for the VL53L7CX main 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 VL53L7CX_API_H_ 39 | #define VL53L7CX_API_H_ 40 | 41 | #if defined (__ARMCC_VERSION) && (__ARMCC_VERSION < 6010050) 42 | #pragma anon_unions 43 | #endif 44 | 45 | 46 | 47 | #include "vl53l7cx_platform.h" 48 | 49 | /** 50 | * @brief Current driver version. 51 | */ 52 | 53 | #define VL53L7CX_API_REVISION "VL53L7CX_1.2.3" 54 | 55 | /** 56 | * @brief Default I2C address of VL53L7CX sensor. Can be changed using function 57 | * vl53l7cx_set_i2c_address() function is called. 58 | */ 59 | 60 | #define VL53L7CX_DEFAULT_I2C_ADDRESS ((uint16_t)0x52) 61 | 62 | /** 63 | * @brief Macro VL53L7CX_RESOLUTION_4X4 or VL53L7CX_RESOLUTION_8X8 allows 64 | * setting sensor in 4x4 mode or 8x8 mode, using function 65 | * vl53l7cx_set_resolution(). 66 | */ 67 | 68 | #define VL53L7CX_RESOLUTION_4X4 ((uint8_t) 16U) 69 | #define VL53L7CX_RESOLUTION_8X8 ((uint8_t) 64U) 70 | 71 | 72 | /** 73 | * @brief Macro VL53L7CX_TARGET_ORDER_STRONGEST or VL53L7CX_TARGET_ORDER_CLOSEST 74 | * are used to select the target order for data output. 75 | */ 76 | 77 | #define VL53L7CX_TARGET_ORDER_CLOSEST ((uint8_t) 1U) 78 | #define VL53L7CX_TARGET_ORDER_STRONGEST ((uint8_t) 2U) 79 | 80 | /** 81 | * @brief Macro VL53L7CX_RANGING_MODE_CONTINUOUS and 82 | * VL53L7CX_RANGING_MODE_AUTONOMOUS are used to change the ranging mode. 83 | * Autonomous mode can be used to set a precise integration time, whereas 84 | * continuous is always maximum. 85 | */ 86 | 87 | #define VL53L7CX_RANGING_MODE_CONTINUOUS ((uint8_t) 1U) 88 | #define VL53L7CX_RANGING_MODE_AUTONOMOUS ((uint8_t) 3U) 89 | 90 | /** 91 | * @brief The default power mode is VL53L7CX_POWER_MODE_WAKEUP. User can choose 92 | * the mode VL53L7CX_POWER_MODE_SLEEP to save power consumption is the device 93 | * is not used. The low power mode retains the firmware and the configuration. 94 | * Both modes can be changed using function vl53l7cx_set_power_mode(). 95 | */ 96 | 97 | #define VL53L7CX_POWER_MODE_SLEEP ((uint8_t) 0U) 98 | #define VL53L7CX_POWER_MODE_WAKEUP ((uint8_t) 1U) 99 | 100 | /** 101 | * @brief Macro VL53L7CX_STATUS_OK indicates that VL53L5 sensor has no error. 102 | * Macro VL53L7CX_STATUS_ERROR indicates that something is wrong (value, 103 | * I2C access, ...). Macro VL53L7CX_MCU_ERROR is used to indicate a MCU issue. 104 | */ 105 | 106 | #define VL53L7CX_STATUS_OK ((uint8_t) 0U) 107 | #define VL53L7CX_STATUS_TIMEOUT_ERROR ((uint8_t) 1U) 108 | #define VL53L7CX_STATUS_CORRUPTED_FRAME ((uint8_t) 2U) 109 | #define VL53L7CX_MCU_ERROR ((uint8_t) 66U) 110 | #define VL53L7CX_STATUS_INVALID_PARAM ((uint8_t) 127U) 111 | #define VL53L7CX_STATUS_ERROR ((uint8_t) 255U) 112 | 113 | /** 114 | * @brief Definitions for Range results block headers 115 | */ 116 | 117 | #if VL53L7CX_NB_TARGET_PER_ZONE == 1 118 | 119 | #define VL53L7CX_START_BH ((uint32_t)0x0000000DU) 120 | #define VL53L7CX_METADATA_BH ((uint32_t)0x54B400C0U) 121 | #define VL53L7CX_COMMONDATA_BH ((uint32_t)0x54C00040U) 122 | #define VL53L7CX_AMBIENT_RATE_BH ((uint32_t)0x54D00104U) 123 | #define VL53L7CX_SPAD_COUNT_BH ((uint32_t)0x55D00404U) 124 | #define VL53L7CX_NB_TARGET_DETECTED_BH ((uint32_t)0xCF7C0401U) 125 | #define VL53L7CX_SIGNAL_RATE_BH ((uint32_t)0xCFBC0404U) 126 | #define VL53L7CX_RANGE_SIGMA_MM_BH ((uint32_t)0xD2BC0402U) 127 | #define VL53L7CX_DISTANCE_BH ((uint32_t)0xD33C0402U) 128 | #define VL53L7CX_REFLECTANCE_BH ((uint32_t)0xD43C0401U) 129 | #define VL53L7CX_TARGET_STATUS_BH ((uint32_t)0xD47C0401U) 130 | #define VL53L7CX_MOTION_DETECT_BH ((uint32_t)0xCC5008C0U) 131 | 132 | #define VL53L7CX_METADATA_IDX ((uint16_t)0x54B4U) 133 | #define VL53L7CX_SPAD_COUNT_IDX ((uint16_t)0x55D0U) 134 | #define VL53L7CX_AMBIENT_RATE_IDX ((uint16_t)0x54D0U) 135 | #define VL53L7CX_NB_TARGET_DETECTED_IDX ((uint16_t)0xCF7CU) 136 | #define VL53L7CX_SIGNAL_RATE_IDX ((uint16_t)0xCFBCU) 137 | #define VL53L7CX_RANGE_SIGMA_MM_IDX ((uint16_t)0xD2BCU) 138 | #define VL53L7CX_DISTANCE_IDX ((uint16_t)0xD33CU) 139 | #define VL53L7CX_REFLECTANCE_EST_PC_IDX ((uint16_t)0xD43CU) 140 | #define VL53L7CX_TARGET_STATUS_IDX ((uint16_t)0xD47CU) 141 | #define VL53L7CX_MOTION_DETEC_IDX ((uint16_t)0xCC50U) 142 | 143 | #else 144 | #define VL53L7CX_START_BH ((uint32_t)0x0000000DU) 145 | #define VL53L7CX_METADATA_BH ((uint32_t)0x54B400C0U) 146 | #define VL53L7CX_COMMONDATA_BH ((uint32_t)0x54C00040U) 147 | #define VL53L7CX_AMBIENT_RATE_BH ((uint32_t)0x54D00104U) 148 | #define VL53L7CX_NB_TARGET_DETECTED_BH ((uint32_t)0x57D00401U) 149 | #define VL53L7CX_SPAD_COUNT_BH ((uint32_t)0x55D00404U) 150 | #define VL53L7CX_SIGNAL_RATE_BH ((uint32_t)0x58900404U) 151 | #define VL53L7CX_RANGE_SIGMA_MM_BH ((uint32_t)0x64900402U) 152 | #define VL53L7CX_DISTANCE_BH ((uint32_t)0x66900402U) 153 | #define VL53L7CX_REFLECTANCE_BH ((uint32_t)0x6A900401U) 154 | #define VL53L7CX_TARGET_STATUS_BH ((uint32_t)0x6B900401U) 155 | #define VL53L7CX_MOTION_DETECT_BH ((uint32_t)0xCC5008C0U) 156 | 157 | #define VL53L7CX_METADATA_IDX ((uint16_t)0x54B4U) 158 | #define VL53L7CX_SPAD_COUNT_IDX ((uint16_t)0x55D0U) 159 | #define VL53L7CX_AMBIENT_RATE_IDX ((uint16_t)0x54D0U) 160 | #define VL53L7CX_NB_TARGET_DETECTED_IDX ((uint16_t)0x57D0U) 161 | #define VL53L7CX_SIGNAL_RATE_IDX ((uint16_t)0x5890U) 162 | #define VL53L7CX_RANGE_SIGMA_MM_IDX ((uint16_t)0x6490U) 163 | #define VL53L7CX_DISTANCE_IDX ((uint16_t)0x6690U) 164 | #define VL53L7CX_REFLECTANCE_EST_PC_IDX ((uint16_t)0x6A90U) 165 | #define VL53L7CX_TARGET_STATUS_IDX ((uint16_t)0x6B90U) 166 | #define VL53L7CX_MOTION_DETEC_IDX ((uint16_t)0xCC50U) 167 | #endif 168 | 169 | 170 | /** 171 | * @brief Inner Macro for API. Not for user, only for development. 172 | */ 173 | 174 | #define VL53L7CX_NVM_DATA_SIZE ((uint16_t)492U) 175 | #define VL53L7CX_CONFIGURATION_SIZE ((uint16_t)972U) 176 | #define VL53L7CX_OFFSET_BUFFER_SIZE ((uint16_t)488U) 177 | #define VL53L7CX_XTALK_BUFFER_SIZE ((uint16_t)776U) 178 | 179 | #define VL53L7CX_DCI_ZONE_CONFIG ((uint16_t)0x5450U) 180 | #define VL53L7CX_DCI_FREQ_HZ ((uint16_t)0x5458U) 181 | #define VL53L7CX_DCI_INT_TIME ((uint16_t)0x545CU) 182 | #define VL53L7CX_DCI_FW_NB_TARGET ((uint16_t)0x5478) 183 | #define VL53L7CX_DCI_RANGING_MODE ((uint16_t)0xAD30U) 184 | #define VL53L7CX_DCI_DSS_CONFIG ((uint16_t)0xAD38U) 185 | #define VL53L7CX_DCI_TARGET_ORDER ((uint16_t)0xAE64U) 186 | #define VL53L7CX_DCI_SHARPENER ((uint16_t)0xAED8U) 187 | #define VL53L7CX_DCI_INTERNAL_CP ((uint16_t)0xB39CU) 188 | #define VL53L7CX_DCI_MOTION_DETECTOR_CFG ((uint16_t)0xBFACU) 189 | #define VL53L7CX_DCI_SINGLE_RANGE ((uint16_t)0xCD5CU) 190 | #define VL53L7CX_DCI_OUTPUT_CONFIG ((uint16_t)0xCD60U) 191 | #define VL53L7CX_DCI_OUTPUT_ENABLES ((uint16_t)0xCD68U) 192 | #define VL53L7CX_DCI_OUTPUT_LIST ((uint16_t)0xCD78U) 193 | #define VL53L7CX_DCI_PIPE_CONTROL ((uint16_t)0xCF78U) 194 | 195 | #define VL53L7CX_UI_CMD_STATUS ((uint16_t)0x2C00U) 196 | #define VL53L7CX_UI_CMD_START ((uint16_t)0x2C04U) 197 | #define VL53L7CX_UI_CMD_END ((uint16_t)0x2FFFU) 198 | 199 | /** 200 | * @brief Inner values for API. Max buffer size depends of the selected output. 201 | */ 202 | 203 | #ifndef VL53L7CX_DISABLE_AMBIENT_PER_SPAD 204 | #define L5CX_AMB_SIZE 260U 205 | #else 206 | #define L5CX_AMB_SIZE 0U 207 | #endif 208 | 209 | #ifndef VL53L7CX_DISABLE_NB_SPADS_ENABLED 210 | #define L5CX_SPAD_SIZE 260U 211 | #else 212 | #define L5CX_SPAD_SIZE 0U 213 | #endif 214 | 215 | #ifndef VL53L7CX_DISABLE_NB_TARGET_DETECTED 216 | #define L5CX_NTAR_SIZE 68U 217 | #else 218 | #define L5CX_NTAR_SIZE 0U 219 | #endif 220 | 221 | #ifndef VL53L7CX_DISABLE_SIGNAL_PER_SPAD 222 | #define L5CX_SPS_SIZE ((256U * VL53L7CX_NB_TARGET_PER_ZONE) + 4U) 223 | #else 224 | #define L5CX_SPS_SIZE 0U 225 | #endif 226 | 227 | #ifndef VL53L7CX_DISABLE_RANGE_SIGMA_MM 228 | #define L5CX_SIGR_SIZE ((128U * VL53L7CX_NB_TARGET_PER_ZONE) + 4U) 229 | #else 230 | #define L5CX_SIGR_SIZE 0U 231 | #endif 232 | 233 | #ifndef VL53L7CX_DISABLE_DISTANCE_MM 234 | #define L5CX_DIST_SIZE ((128U * VL53L7CX_NB_TARGET_PER_ZONE) + 4U) 235 | #else 236 | #define L5CX_DIST_SIZE 0U 237 | #endif 238 | 239 | #ifndef VL53L7CX_DISABLE_REFLECTANCE_PERCENT 240 | #define L5CX_RFLEST_SIZE ((64U *VL53L7CX_NB_TARGET_PER_ZONE) + 4U) 241 | #else 242 | #define L5CX_RFLEST_SIZE 0U 243 | #endif 244 | 245 | #ifndef VL53L7CX_DISABLE_TARGET_STATUS 246 | #define L5CX_STA_SIZE ((64U *VL53L7CX_NB_TARGET_PER_ZONE) + 4U) 247 | #else 248 | #define L5CX_STA_SIZE 0U 249 | #endif 250 | 251 | #ifndef VL53L7CX_DISABLE_MOTION_INDICATOR 252 | #define L5CX_MOT_SIZE 144U 253 | #else 254 | #define L5CX_MOT_SIZE 0U 255 | #endif 256 | 257 | /** 258 | * @brief Macro VL53L7CX_MAX_RESULTS_SIZE indicates the maximum size used by 259 | * output through I2C. Value 40 corresponds to headers + meta-data + common-data 260 | * and 20 corresponds to the footer. 261 | */ 262 | 263 | #define VL53L7CX_MAX_RESULTS_SIZE ( 40U \ 264 | + L5CX_AMB_SIZE + L5CX_SPAD_SIZE + L5CX_NTAR_SIZE + L5CX_SPS_SIZE \ 265 | + L5CX_SIGR_SIZE + L5CX_DIST_SIZE + L5CX_RFLEST_SIZE + L5CX_STA_SIZE \ 266 | + L5CX_MOT_SIZE + 20U) 267 | 268 | /** 269 | * @brief Macro VL53L7CX_TEMPORARY_BUFFER_SIZE can be used to know the size of 270 | * the temporary buffer. The minimum size is 1024, and the maximum depends of 271 | * the output configuration. 272 | */ 273 | 274 | #if VL53L7CX_MAX_RESULTS_SIZE < 1024U 275 | #define VL53L7CX_TEMPORARY_BUFFER_SIZE ((uint32_t) 1024U) 276 | #else 277 | #define VL53L7CX_TEMPORARY_BUFFER_SIZE ((uint32_t) VL53L7CX_MAX_RESULTS_SIZE) 278 | #endif 279 | 280 | 281 | /** 282 | * @brief Structure VL53L7CX_Configuration contains the sensor configuration. 283 | * User MUST not manually change these field, except for the sensor address. 284 | */ 285 | 286 | typedef struct { 287 | /* Platform, filled by customer into the 'platform.h' file */ 288 | VL53L7CX_Platform platform; 289 | /* Results streamcount, value auto-incremented at each range */ 290 | uint8_t streamcount; 291 | /* Size of data read though I2C */ 292 | uint32_t data_read_size; 293 | /* Address of default configuration buffer */ 294 | uint8_t *default_configuration; 295 | /* Address of default Xtalk buffer */ 296 | uint8_t *default_xtalk; 297 | /* Offset buffer */ 298 | uint8_t offset_data[VL53L7CX_OFFSET_BUFFER_SIZE]; 299 | /* Xtalk buffer */ 300 | uint8_t xtalk_data[VL53L7CX_XTALK_BUFFER_SIZE]; 301 | /* Temporary buffer used for internal driver processing */ 302 | uint8_t temp_buffer[VL53L7CX_TEMPORARY_BUFFER_SIZE]; 303 | } VL53L7CX_Configuration; 304 | 305 | 306 | /** 307 | * @brief Structure VL53L7CX_ResultsData contains the ranging results of 308 | * VL53L7CX. If user wants more than 1 target per zone, the results can be split 309 | * into 2 sub-groups : 310 | * - Per zone results. These results are common to all targets (ambient_per_spad 311 | * , nb_target_detected and nb_spads_enabled). 312 | * - Per target results : These results are different relative to the detected 313 | * target (signal_per_spad, range_sigma_mm, distance_mm, reflectance, 314 | * target_status). 315 | */ 316 | 317 | typedef struct { 318 | /* Internal sensor silicon temperature */ 319 | int8_t silicon_temp_degc; 320 | 321 | /* Ambient noise in kcps/spads */ 322 | #ifndef VL53L7CX_DISABLE_AMBIENT_PER_SPAD 323 | uint32_t ambient_per_spad[VL53L7CX_RESOLUTION_8X8]; 324 | #endif 325 | 326 | /* Number of valid target detected for 1 zone */ 327 | #ifndef VL53L7CX_DISABLE_NB_TARGET_DETECTED 328 | uint8_t nb_target_detected[VL53L7CX_RESOLUTION_8X8]; 329 | #endif 330 | 331 | /* Number of spads enabled for this ranging */ 332 | #ifndef VL53L7CX_DISABLE_NB_SPADS_ENABLED 333 | uint32_t nb_spads_enabled[VL53L7CX_RESOLUTION_8X8]; 334 | #endif 335 | 336 | /* Signal returned to the sensor in kcps/spads */ 337 | #ifndef VL53L7CX_DISABLE_SIGNAL_PER_SPAD 338 | uint32_t signal_per_spad[(VL53L7CX_RESOLUTION_8X8 339 | *VL53L7CX_NB_TARGET_PER_ZONE)]; 340 | #endif 341 | 342 | /* Sigma of the current distance in mm */ 343 | #ifndef VL53L7CX_DISABLE_RANGE_SIGMA_MM 344 | uint16_t range_sigma_mm[(VL53L7CX_RESOLUTION_8X8 345 | *VL53L7CX_NB_TARGET_PER_ZONE)]; 346 | #endif 347 | 348 | /* Measured distance in mm */ 349 | #ifndef VL53L7CX_DISABLE_DISTANCE_MM 350 | int16_t distance_mm[(VL53L7CX_RESOLUTION_8X8 351 | *VL53L7CX_NB_TARGET_PER_ZONE)]; 352 | #endif 353 | 354 | /* Estimated reflectance in percent */ 355 | #ifndef VL53L7CX_DISABLE_REFLECTANCE_PERCENT 356 | uint8_t reflectance[(VL53L7CX_RESOLUTION_8X8 357 | *VL53L7CX_NB_TARGET_PER_ZONE)]; 358 | #endif 359 | 360 | /* Status indicating the measurement validity (5 & 9 means ranging OK)*/ 361 | #ifndef VL53L7CX_DISABLE_TARGET_STATUS 362 | uint8_t target_status[(VL53L7CX_RESOLUTION_8X8 363 | *VL53L7CX_NB_TARGET_PER_ZONE)]; 364 | #endif 365 | 366 | /* Motion detector results */ 367 | #ifndef VL53L7CX_DISABLE_MOTION_INDICATOR 368 | struct { 369 | uint32_t global_indicator_1; 370 | uint32_t global_indicator_2; 371 | uint8_t status; 372 | uint8_t nb_of_detected_aggregates; 373 | uint8_t nb_of_aggregates; 374 | uint8_t spare; 375 | uint32_t motion[32]; 376 | } motion_indicator; 377 | #endif 378 | 379 | } VL53L7CX_ResultsData; 380 | 381 | #ifndef BLOCK_HEADER 382 | #define BLOCK_HEADER 383 | union Block_header { 384 | uint32_t bytes; 385 | struct { 386 | uint32_t type : 4; 387 | uint32_t size : 12; 388 | uint32_t idx : 16; 389 | }; 390 | }; 391 | #endif 392 | 393 | #endif //VL53L7CX_API_H_ 394 | -------------------------------------------------------------------------------- /src/vl53l7cx_class.h: -------------------------------------------------------------------------------- 1 | /** 2 | ****************************************************************************** 3 | * @file vl53l7cx_class.h 4 | * @author STMicroelectronics 5 | * @version V1.0.0 6 | * @date 13 January 2023 7 | * @brief Abstract Class for VL53L7CX sensor. 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 __VL53L7CX_CLASS_H 39 | #define __VL53L7CX_CLASS_H 40 | 41 | /* Includes ------------------------------------------------------------------*/ 42 | #include "Arduino.h" 43 | #include "vl53l7cx_platform.h" 44 | #include "vl53l7cx_api.h" 45 | #include "vl53l7cx_plugin_detection_thresholds.h" 46 | #include "vl53l7cx_plugin_motion_indicator.h" 47 | #include "vl53l7cx_plugin_xtalk.h" 48 | 49 | 50 | 51 | 52 | /* Classes -------------------------------------------------------------------*/ 53 | /** Class representing a VL53LX sensor component 54 | */ 55 | 56 | class VL53L7CX { 57 | public: 58 | /** Constructor 59 | * @param[in] i2c device I2C to be used for communication 60 | * @param[in] lpn_pin pin to be used as component LPn 61 | * @param[in] i2c_rst_pin pin to be used as component I2C_RST 62 | */ 63 | VL53L7CX(TwoWire *i2c, int lpn_pin, int i2c_rst_pin = -1) 64 | { 65 | memset((void *)&_dev, 0x0, sizeof(VL53L7CX_Configuration)); 66 | _dev.platform.address = VL53L7CX_DEFAULT_I2C_ADDRESS; 67 | _dev.platform.dev_i2c = i2c; 68 | _dev.platform.lpn_pin = lpn_pin; 69 | _dev.platform.i2c_rst_pin = i2c_rst_pin; 70 | p_dev = &_dev; 71 | } 72 | 73 | 74 | /** Destructor 75 | */ 76 | virtual ~VL53L7CX() {} 77 | /* warning: VL53LX class inherits from GenericSensor, RangeSensor and LightSensor, that haven`t a destructor. 78 | The warning should request to introduce a virtual destructor to make sure to delete the object */ 79 | 80 | virtual int begin() 81 | { 82 | if (_dev.platform.lpn_pin >= 0) { 83 | pinMode(_dev.platform.lpn_pin, OUTPUT); 84 | digitalWrite(_dev.platform.lpn_pin, LOW); 85 | } 86 | if (_dev.platform.i2c_rst_pin >= 0) { 87 | pinMode(_dev.platform.i2c_rst_pin, OUTPUT); 88 | digitalWrite(_dev.platform.i2c_rst_pin, LOW); 89 | } 90 | return 0; 91 | } 92 | 93 | virtual int end() 94 | { 95 | if (_dev.platform.lpn_pin >= 0) { 96 | pinMode(_dev.platform.lpn_pin, INPUT); 97 | } 98 | if (_dev.platform.i2c_rst_pin >= 0) { 99 | pinMode(_dev.platform.i2c_rst_pin, INPUT); 100 | } 101 | return 0; 102 | } 103 | 104 | /*** Interface Methods ***/ 105 | /*** High level API ***/ 106 | /** 107 | * @brief PowerOn the sensor 108 | * @return void 109 | */ 110 | virtual void vl53l7cx_on(void) 111 | { 112 | if (_dev.platform.lpn_pin >= 0) { 113 | digitalWrite(_dev.platform.lpn_pin, HIGH); 114 | } 115 | delay(10); 116 | } 117 | 118 | /** 119 | * @brief PowerOff the sensor 120 | * @return void 121 | */ 122 | virtual void vl53l7cx_off(void) 123 | { 124 | if (_dev.platform.lpn_pin >= 0) { 125 | digitalWrite(_dev.platform.lpn_pin, LOW); 126 | } 127 | delay(10); 128 | } 129 | 130 | /** 131 | * @brief Reset I2C peripheral of the sensor 132 | * @return void 133 | */ 134 | virtual void vl53l7cx_i2c_reset(void) 135 | { 136 | if (_dev.platform.i2c_rst_pin >= 0) { 137 | digitalWrite(_dev.platform.i2c_rst_pin, LOW); 138 | delay(10); 139 | digitalWrite(_dev.platform.i2c_rst_pin, HIGH); 140 | delay(10); 141 | digitalWrite(_dev.platform.i2c_rst_pin, LOW); 142 | delay(10); 143 | } 144 | } 145 | 146 | /** 147 | * @brief Initialize the sensor 148 | * @param (uint8_t) addr : New I2C address. 149 | * @return (uint8_t) status : 0 if init_sensor is OK. 150 | */ 151 | int init_sensor(uint8_t addr = VL53L7CX_DEFAULT_I2C_ADDRESS) 152 | { 153 | uint8_t status = VL53L7CX_STATUS_OK; 154 | uint8_t isAlive = 0; 155 | 156 | // Reset the sensor by toggling the LPN pin 157 | vl53l7cx_off(); 158 | vl53l7cx_on(); 159 | if (addr != _dev.platform.address) { 160 | status = vl53l7cx_set_i2c_address(addr); 161 | if (status != VL53L7CX_STATUS_OK) { 162 | return VL53L7CX_STATUS_ERROR; 163 | } 164 | } 165 | 166 | status = vl53l7cx_is_alive(&isAlive); 167 | if (!isAlive || status != VL53L7CX_STATUS_OK) { 168 | return VL53L7CX_STATUS_ERROR; 169 | } 170 | 171 | // Init VL53L7CX sensor 172 | status = vl53l7cx_init(); 173 | if (status != VL53L7CX_STATUS_OK) { 174 | return VL53L7CX_STATUS_ERROR; 175 | } 176 | 177 | return (int)status; 178 | } 179 | 180 | 181 | /* vl53l7cx_api.h */ 182 | /** 183 | * @brief This function is used to check if the sensor is alive. 184 | * @param (uint8_t) *p_is_alive : 1 if the sensor is alive, 0 in case of error. 185 | * @return (uint8_t) status : 0 if is_alive is OK. 186 | */ 187 | uint8_t vl53l7cx_is_alive( 188 | uint8_t *p_is_alive); 189 | 190 | /** 191 | * @brief Mandatory function used to initialize the sensor. This function must 192 | * be called after a power on, to load the firmware into the VL53L7CX. It takes 193 | * a few hundred milliseconds. 194 | * @return (uint8_t) status : 0 if initialization is OK. 195 | */ 196 | 197 | uint8_t vl53l7cx_init(); 198 | 199 | /** 200 | * @brief This function is used to change the I2C address of the sensor. If 201 | * multiple VL53L7 sensors are connected to the same I2C line, all other LPn 202 | * pins needs to be set to Low. The default sensor address is 0x52. 203 | * @param (uint16_t) i2c_address : New I2C address. 204 | * @return (uint8_t) status : 0 if new address is OK 205 | */ 206 | 207 | uint8_t vl53l7cx_set_i2c_address( 208 | uint16_t i2c_address); 209 | 210 | /** 211 | * @brief This function is used to get the current sensor power mode. 212 | * @param (uint8_t) *p_power_mode : Current power mode. The value of this 213 | * pointer is equal to 0 if the sensor is in low power, 214 | * (VL53L7CX_POWER_MODE_SLEEP), or 1 if sensor is in standard mode 215 | * (VL53L7CX_POWER_MODE_WAKEUP). 216 | * @return (uint8_t) status : 0 if power mode is OK 217 | */ 218 | 219 | uint8_t vl53l7cx_get_power_mode( 220 | uint8_t *p_power_mode); 221 | 222 | /** 223 | * @brief This function is used to set the sensor in Low Power mode, for 224 | * example if the sensor is not used during a long time. The macro 225 | * VL53L7CX_POWER_MODE_SLEEP can be used to enable the low power mode. When user 226 | * want to restart the sensor, he can use macro VL53L7CX_POWER_MODE_WAKEUP. 227 | * Please ensure that the device is not streaming before calling the function. 228 | * @param (uint8_t) power_mode : Selected power mode (VL53L7CX_POWER_MODE_SLEEP 229 | * or VL53L7CX_POWER_MODE_WAKEUP) 230 | * @return (uint8_t) status : 0 if power mode is OK, or 127 if power mode 231 | * requested by user is not valid. 232 | */ 233 | 234 | uint8_t vl53l7cx_set_power_mode( 235 | uint8_t power_mode); 236 | 237 | /** 238 | * @brief This function starts a ranging session. When the sensor streams, host 239 | * cannot change settings 'on-the-fly'. 240 | * @return (uint8_t) status : 0 if start is OK. 241 | */ 242 | 243 | uint8_t vl53l7cx_start_ranging(); 244 | 245 | /** 246 | * @brief This function stops the ranging session. It must be used when the 247 | * sensor streams, after calling vl53l7cx_start_ranging(). 248 | * @return (uint8_t) status : 0 if stop is OK 249 | */ 250 | 251 | uint8_t vl53l7cx_stop_ranging(); 252 | 253 | /** 254 | * @brief This function checks if a new data is ready by polling I2C. If a new 255 | * data is ready, a flag will be raised. 256 | * @param (uint8_t) *p_isReady : Value of this pointer be updated to 0 if data 257 | * is not ready, or 1 if a new data is ready. 258 | * @return (uint8_t) status : 0 if I2C reading is OK 259 | */ 260 | 261 | uint8_t vl53l7cx_check_data_ready( 262 | uint8_t *p_isReady); 263 | 264 | /** 265 | * @brief This function gets the ranging data, using the selected output and the 266 | * resolution. 267 | * @param (VL53L7CX_ResultsData) *p_results : VL53L7 results structure. 268 | * @return (uint8_t) status : 0 data are successfully get. 269 | */ 270 | 271 | uint8_t vl53l7cx_get_ranging_data( 272 | VL53L7CX_ResultsData *p_results); 273 | 274 | /** 275 | * @brief This function gets the current resolution (4x4 or 8x8). 276 | * @param (uint8_t) *p_resolution : Value of this pointer will be equal to 16 277 | * for 4x4 mode, and 64 for 8x8 mode. 278 | * @return (uint8_t) status : 0 if resolution is OK. 279 | */ 280 | 281 | uint8_t vl53l7cx_get_resolution( 282 | uint8_t *p_resolution); 283 | 284 | /** 285 | * @brief This function sets a new resolution (4x4 or 8x8). 286 | * @param (uint8_t) resolution : Use macro VL53L7CX_RESOLUTION_4X4 or 287 | * VL53L7CX_RESOLUTION_8X8 to set the resolution. 288 | * @return (uint8_t) status : 0 if set resolution is OK. 289 | */ 290 | 291 | uint8_t vl53l7cx_set_resolution( 292 | uint8_t resolution); 293 | 294 | /** 295 | * @brief This function gets the current ranging frequency in Hz. Ranging 296 | * frequency corresponds to the time between each measurement. 297 | * @param (uint8_t) *p_frequency_hz: Contains the ranging frequency in Hz. 298 | * @return (uint8_t) status : 0 if ranging frequency is OK. 299 | */ 300 | 301 | uint8_t vl53l7cx_get_ranging_frequency_hz( 302 | uint8_t *p_frequency_hz); 303 | 304 | /** 305 | * @brief This function sets a new ranging frequency in Hz. Ranging frequency 306 | * corresponds to the measurements frequency. This setting depends of 307 | * the resolution, so please select your resolution before using this function. 308 | * @param (uint8_t) frequency_hz : Contains the ranging frequency in Hz. 309 | * - For 4x4, min and max allowed values are : [1;60] 310 | * - For 8x8, min and max allowed values are : [1;15] 311 | * @return (uint8_t) status : 0 if ranging frequency is OK, or 127 if the value 312 | * is not correct. 313 | */ 314 | 315 | uint8_t vl53l7cx_set_ranging_frequency_hz( 316 | uint8_t frequency_hz); 317 | 318 | /** 319 | * @brief This function gets the current integration time in ms. 320 | * @param (uint32_t) *p_time_ms: Contains integration time in ms. 321 | * @return (uint8_t) status : 0 if integration time is OK. 322 | */ 323 | 324 | uint8_t vl53l7cx_get_integration_time_ms( 325 | uint32_t *p_time_ms); 326 | 327 | /** 328 | * @brief This function sets a new integration time in ms. Integration time must 329 | * be computed to be lower than the ranging period, for a selected resolution. 330 | * Please note that this function has no impact on ranging mode continuous. 331 | * @param (uint32_t) time_ms : Contains the integration time in ms. For all 332 | * resolutions and frequency, the minimum value is 2ms, and the maximum is 333 | * 1000ms. 334 | * @return (uint8_t) status : 0 if set integration time is OK. 335 | */ 336 | 337 | uint8_t vl53l7cx_set_integration_time_ms( 338 | uint32_t integration_time_ms); 339 | 340 | /** 341 | * @brief This function gets the current sharpener in percent. Sharpener can be 342 | * changed to blur more or less zones depending of the application. 343 | * @param (uint32_t) *p_sharpener_percent: Contains the sharpener in percent. 344 | * @return (uint8_t) status : 0 if get sharpener is OK. 345 | */ 346 | 347 | uint8_t vl53l7cx_get_sharpener_percent( 348 | uint8_t *p_sharpener_percent); 349 | 350 | /** 351 | * @brief This function sets a new sharpener value in percent. Sharpener can be 352 | * changed to blur more or less zones depending of the application. Min value is 353 | * 0 (disabled), and max is 99. 354 | * @param (uint32_t) sharpener_percent : Value between 0 (disabled) and 99%. 355 | * @return (uint8_t) status : 0 if set sharpener is OK. 356 | */ 357 | 358 | uint8_t vl53l7cx_set_sharpener_percent( 359 | uint8_t sharpener_percent); 360 | 361 | /** 362 | * @brief This function gets the current target order (closest or strongest). 363 | * @param (uint8_t) *p_target_order: Contains the target order. 364 | * @return (uint8_t) status : 0 if get target order is OK. 365 | */ 366 | 367 | uint8_t vl53l7cx_get_target_order( 368 | uint8_t *p_target_order); 369 | 370 | /** 371 | * @brief This function sets a new target order. Please use macros 372 | * VL53L7CX_TARGET_ORDER_STRONGEST and VL53L7CX_TARGET_ORDER_CLOSEST to define 373 | * the new output order. By default, the sensor is configured with the strongest 374 | * output. 375 | * @param (uint8_t) target_order : Required target order. 376 | * @return (uint8_t) status : 0 if set target order is OK, or 127 if target 377 | * order is unknown. 378 | */ 379 | 380 | uint8_t vl53l7cx_set_target_order( 381 | uint8_t target_order); 382 | 383 | /** 384 | * @brief This function is used to get the ranging mode. Two modes are 385 | * available using ULD : Continuous and autonomous. The default 386 | * mode is Autonomous. 387 | * @param (uint8_t) *p_ranging_mode : current ranging mode 388 | * @return (uint8_t) status : 0 if get ranging mode is OK. 389 | */ 390 | 391 | uint8_t vl53l7cx_get_ranging_mode( 392 | uint8_t *p_ranging_mode); 393 | 394 | /** 395 | * @brief This function is used to set the ranging mode. Two modes are 396 | * available using ULD : Continuous and autonomous. The default 397 | * mode is Autonomous. 398 | * @param (uint8_t) ranging_mode : Use macros VL53L7CX_RANGING_MODE_CONTINUOUS, 399 | * VL53L7CX_RANGING_MODE_CONTINUOUS. 400 | * @return (uint8_t) status : 0 if set ranging mode is OK. 401 | */ 402 | 403 | uint8_t vl53l7cx_set_ranging_mode( 404 | uint8_t ranging_mode); 405 | 406 | /** 407 | * @brief This function can be used to read 'extra data' from DCI. Using a known 408 | * index, the function fills the casted structure passed in argument. 409 | * @param (uint8_t) *data : This field can be a casted structure, or a simple 410 | * array. Please note that the FW only accept data of 32 bits. So field data can 411 | * only have a size of 32, 64, 96, 128, bits .... 412 | * @param (uint32_t) index : Index of required value. 413 | * @param (uint16_t)*data_size : This field must be the structure or array size 414 | * (using sizeof() function). 415 | * @return (uint8_t) status : 0 if OK 416 | */ 417 | 418 | uint8_t vl53l7cx_dci_read_data( 419 | uint8_t *data, 420 | uint32_t index, 421 | uint16_t data_size); 422 | 423 | /** 424 | * @brief This function can be used to write 'extra data' to DCI. The data can 425 | * be simple data, or casted structure. 426 | * @param (uint8_t) *data : This field can be a casted structure, or a simple 427 | * array. Please note that the FW only accept data of 32 bits. So field data can 428 | * only have a size of 32, 64, 96, 128, bits .. 429 | * @param (uint32_t) index : Index of required value. 430 | * @param (uint16_t)*data_size : This field must be the structure or array size 431 | * (using sizeof() function). 432 | * @return (uint8_t) status : 0 if OK 433 | */ 434 | 435 | uint8_t vl53l7cx_dci_write_data( 436 | uint8_t *data, 437 | uint32_t index, 438 | uint16_t data_size); 439 | 440 | /** 441 | * @brief This function can be used to replace 'extra data' in DCI. The data can 442 | * be simple data, or casted structure. 443 | * @param (uint8_t) *data : This field can be a casted structure, or a simple 444 | * array. Please note that the FW only accept data of 32 bits. So field data can 445 | * only have a size of 32, 64, 96, 128, bits .. 446 | * @param (uint32_t) index : Index of required value. 447 | * @param (uint16_t)*data_size : This field must be the structure or array size 448 | * (using sizeof() function). 449 | * @param (uint8_t) *new_data : Contains the new fields. 450 | * @param (uint16_t) new_data_size : New data size. 451 | * @param (uint16_t) new_data_pos : New data position into the buffer. 452 | * @return (uint8_t) status : 0 if OK 453 | */ 454 | 455 | uint8_t vl53l7cx_dci_replace_data( 456 | uint8_t *data, 457 | uint32_t index, 458 | uint16_t data_size, 459 | uint8_t *new_data, 460 | uint16_t new_data_size, 461 | uint16_t new_data_pos); 462 | 463 | 464 | /* Thresholds Detection APIs */ 465 | 466 | /** 467 | * @brief This function allows indicating if the detection thresholds are 468 | * enabled. 469 | * @param (uint8_t) *p_enabled : Set to 1 if enabled, or 0 if disable. 470 | * @return (uint8_t) status : 0 if OK 471 | */ 472 | 473 | uint8_t vl53l7cx_get_detection_thresholds_enable( 474 | uint8_t *p_enabled); 475 | 476 | /** 477 | * @brief This function allows enable the detection thresholds. 478 | * @param (uint8_t) enabled : Set to 1 to enable, or 0 to disable thresholds. 479 | * @return (uint8_t) status : 0 if programming is OK 480 | */ 481 | 482 | uint8_t vl53l7cx_set_detection_thresholds_enable( 483 | uint8_t enabled); 484 | 485 | /** 486 | * @brief This function allows getting the detection thresholds. 487 | * @param (VL53L7CX_DetectionThresholds) *p_thresholds : Array of 64 thresholds. 488 | * @return (uint8_t) status : 0 if programming is OK 489 | */ 490 | 491 | uint8_t vl53l7cx_get_detection_thresholds( 492 | VL53L7CX_DetectionThresholds *p_thresholds); 493 | 494 | /** 495 | * @brief This function allows programming the detection thresholds. 496 | * @param (VL53L7CX_DetectionThresholds) *p_thresholds : Array of 64 thresholds. 497 | * @return (uint8_t) status : 0 if programming is OK 498 | */ 499 | 500 | uint8_t vl53l7cx_set_detection_thresholds( 501 | VL53L7CX_DetectionThresholds *p_thresholds); 502 | 503 | /* Motion Indicator APIs */ 504 | 505 | /** 506 | * @brief This function is used to initialized the motion indicator. By default, 507 | * indicator is programmed to monitor movements between 400mm and 1500mm. 508 | * @param (VL53L7CX_Motion_Configuration) *p_motion_config : Structure 509 | * containing the initialized motion configuration. 510 | * @param (uint8_t) resolution : Wanted resolution, defined by macros 511 | * VL53L7CX_RESOLUTION_4X4 or VL53L7CX_RESOLUTION_8X8. 512 | * @return (uint8_t) status : 0 if OK, or 127 is the resolution is unknown. 513 | */ 514 | 515 | uint8_t vl53l7cx_motion_indicator_init( 516 | VL53L7CX_Motion_Configuration *p_motion_config, 517 | uint8_t resolution); 518 | 519 | /** 520 | * @brief This function can be used to change the working distance of motion 521 | * indicator. By default, indicator is programmed to monitor movements between 522 | * 400mm and 1500mm. 523 | * @param (VL53L7CX_Motion_Configuration) *p_motion_config : Structure 524 | * containing the initialized motion configuration. 525 | * @param (uint16_t) distance_min_mm : Minimum distance for indicator (min value 526 | * 400mm, max 4000mm). 527 | * @param (uint16_t) distance_max_mm : Maximum distance for indicator (min value 528 | * 400mm, max 4000mm). 529 | * VL53L7CX_RESOLUTION_4X4 or VL53L7CX_RESOLUTION_8X8. 530 | * @return (uint8_t) status : 0 if OK, or 127 if an argument is invalid. 531 | */ 532 | 533 | uint8_t vl53l7cx_motion_indicator_set_distance_motion( 534 | VL53L7CX_Motion_Configuration *p_motion_config, 535 | uint16_t distance_min_mm, 536 | uint16_t distance_max_mm); 537 | 538 | /** 539 | * @brief This function is used to update the internal motion indicator map. 540 | * @param (VL53L7CX_Motion_Configuration) *p_motion_config : Structure 541 | * containing the initialized motion configuration. 542 | * @param (uint8_t) resolution : Wanted SCI resolution, defined by macros 543 | * VL53L7CX_RESOLUTION_4X4 or VL53L7CX_RESOLUTION_8X8. 544 | * @return (uint8_t) status : 0 if OK, or 127 is the resolution is unknown. 545 | */ 546 | 547 | uint8_t vl53l7cx_motion_indicator_set_resolution( 548 | VL53L7CX_Motion_Configuration *p_motion_config, 549 | uint8_t resolution); 550 | 551 | /* XTalk APIs */ 552 | 553 | /** 554 | * @brief This function starts the VL53L7CX sensor in order to calibrate Xtalk. 555 | * This calibration is recommended is user wants to use a coverglass. 556 | * @param (uint16_t) reflectance_percent : Target reflectance in percent. This 557 | * value is include between 1 and 99%. For a better efficiency, ST recommends a 558 | * 3% target reflectance. 559 | * @param (uint8_t) nb_samples : Nb of samples used for calibration. A higher 560 | * number of samples means a higher accuracy, but it increases the calibration 561 | * time. Minimum is 1 and maximum is 16. 562 | * @param (uint16_t) distance_mm : Target distance in mm. The minimum allowed 563 | * distance is 600mm, and maximum is 3000mm. The target must stay in Full FOV, 564 | * so short distance are easier for calibration. 565 | * @return (uint8_t) status : 0 if calibration OK, 127 if an argument has an 566 | * incorrect value, or 255 is something failed. 567 | */ 568 | 569 | uint8_t vl53l7cx_calibrate_xtalk( 570 | uint16_t reflectance_percent, 571 | uint8_t nb_samples, 572 | uint16_t distance_mm); 573 | 574 | /** 575 | * @brief This function gets the Xtalk buffer. The buffer is available after 576 | * using the function vl53l7cx_calibrate_xtalk(). 577 | * @param (uint8_t) *p_xtalk_data : Buffer with a size defined by 578 | * macro VL53L7CX_XTALK_SIZE. 579 | * @return (uint8_t) status : 0 if buffer reading OK 580 | */ 581 | 582 | uint8_t vl53l7cx_get_caldata_xtalk( 583 | uint8_t *p_xtalk_data); 584 | 585 | /** 586 | * @brief This function sets the Xtalk buffer. This function can be used to 587 | * override default Xtalk buffer. 588 | * @param (uint8_t) *p_xtalk_data : Buffer with a size defined by 589 | * macro VL53L7CX_XTALK_SIZE. 590 | * @return (uint8_t) status : 0 if buffer OK 591 | */ 592 | 593 | uint8_t vl53l7cx_set_caldata_xtalk( 594 | uint8_t *p_xtalk_data); 595 | 596 | /** 597 | * @brief This function gets the Xtalk margin. This margin is used to increase 598 | * the Xtalk threshold. It can also be used to avoid false positives after the 599 | * Xtalk calibration. The default value is 50 kcps/spads. 600 | * @param (uint32_t) *p_xtalk_margin : Xtalk margin in kcps/spads. 601 | * @return (uint8_t) status : 0 if reading OK 602 | */ 603 | 604 | uint8_t vl53l7cx_get_xtalk_margin( 605 | uint32_t *p_xtalk_margin); 606 | 607 | /** 608 | * @brief This function sets the Xtalk margin. This margin is used to increase 609 | * the Xtalk threshold. It can also be used to avoid false positives after the 610 | * Xtalk calibration. The default value is 50 kcps/spads. 611 | * @param (uint32_t) xtalk_margin : New Xtalk margin in kcps/spads. Min value is 612 | * 0 kcps/spads, and max is 10.000 kcps/spads 613 | * @return (uint8_t) status : 0 if set margin is OK, or 127 is the margin is 614 | * invalid. 615 | */ 616 | 617 | uint8_t vl53l7cx_set_xtalk_margin( 618 | uint32_t xtalk_margin); 619 | 620 | /** 621 | * @brief Mandatory function, used to swap a buffer. The buffer size is always a 622 | * multiple of 4 (4, 8, 12, 16, ...). 623 | * @param (uint8_t*) buffer : Buffer to swap, generally uint32_t 624 | * @param (uint16_t) size : Buffer size to swap 625 | */ 626 | 627 | void SwapBuffer( 628 | uint8_t *buffer, 629 | uint16_t size); 630 | 631 | /* Helpful APIs */ 632 | uint8_t get_stream_count(void) 633 | { 634 | return _dev.streamcount; 635 | }; 636 | 637 | protected: 638 | 639 | /** 640 | * @brief Inner function, not available outside this file. This function is used 641 | * to wait for an answer from VL53L7CX sensor. 642 | */ 643 | uint8_t _vl53l7cx_poll_for_answer( 644 | uint8_t size, 645 | uint8_t pos, 646 | uint16_t address, 647 | uint8_t mask, 648 | uint8_t expected_value); 649 | /** 650 | * @brief Inner function, not available outside this file. This function is used to 651 | * wait for the MCU to boot. 652 | */ 653 | uint8_t _vl53l7cx_poll_for_mcu_boot(); 654 | /** 655 | * @brief Inner function, not available outside this file. This function is used 656 | * to set the offset data gathered from NVM. 657 | */ 658 | uint8_t _vl53l7cx_send_offset_data( 659 | uint8_t resolution); 660 | 661 | /** 662 | * @brief Inner function, not available outside this file. This function is used 663 | * to set the Xtalk data from generic configuration, or user's calibration. 664 | */ 665 | uint8_t _vl53l7cx_send_xtalk_data( 666 | uint8_t resolution); 667 | 668 | /** 669 | * @brief Inner function, not available outside this file. This function is used to 670 | * wait for an answer from VL53L7 sensor. 671 | */ 672 | uint8_t _vl53l7cx_poll_for_answer_xtalk( 673 | uint16_t address, 674 | uint8_t expected_value); 675 | 676 | /** 677 | * @brief Inner function, not available outside this file. This function is used to 678 | * program the output using the macro defined into the 'platform.h' file. 679 | */ 680 | uint8_t _vl53l7cx_program_output_config(); 681 | 682 | /* Platform APIs */ 683 | 684 | /** 685 | * @param (VL53L7CX_Platform*) p_platform : Pointer of VL53L7CX platform 686 | * structure. 687 | * @param (uint16_t) Address : I2C location of value to read. 688 | * @param (uint8_t) *p_values : Pointer of value to read. 689 | * @return (uint8_t) status : 0 if OK 690 | */ 691 | 692 | uint8_t RdByte( 693 | VL53L7CX_Platform *p_platform, 694 | uint16_t RegisterAddress, 695 | uint8_t *p_value); 696 | 697 | /** 698 | * @brief Mandatory function used to write one single byte. 699 | * @param (VL53L7CX_Platform*) p_platform : Pointer of VL53L7CX platform 700 | * structure. 701 | * @param (uint16_t) Address : I2C location of value to read. 702 | * @param (uint8_t) value : Pointer of value to write. 703 | * @return (uint8_t) status : 0 if OK 704 | */ 705 | 706 | uint8_t WrByte( 707 | VL53L7CX_Platform *p_platform, 708 | uint16_t RegisterAddress, 709 | uint8_t value); 710 | 711 | /** 712 | * @brief Mandatory function used to read multiples bytes. 713 | * @param (VL53L7CX_Platform*) p_platform : Pointer of VL53L7CX platform 714 | * structure. 715 | * @param (uint16_t) Address : I2C location of values to read. 716 | * @param (uint8_t) *p_values : Buffer of bytes to read. 717 | * @param (uint32_t) size : Size of *p_values buffer. 718 | * @return (uint8_t) status : 0 if OK 719 | */ 720 | 721 | uint8_t RdMulti( 722 | VL53L7CX_Platform *p_platform, 723 | uint16_t RegisterAddress, 724 | uint8_t *p_values, 725 | uint32_t size); 726 | 727 | /** 728 | * @brief Mandatory function used to write multiples bytes. 729 | * @param (VL53L7CX_Platform*) p_platform : Pointer of VL53L7CX platform 730 | * structure. 731 | * @param (uint16_t) Address : I2C location of values to write. 732 | * @param (uint8_t) *p_values : Buffer of bytes to write. 733 | * @param (uint32_t) size : Size of *p_values buffer. 734 | * @return (uint8_t) status : 0 if OK 735 | */ 736 | 737 | uint8_t WrMulti( 738 | VL53L7CX_Platform *p_platform, 739 | uint16_t RegisterAddress, 740 | uint8_t *p_values, 741 | uint32_t size); 742 | 743 | /** 744 | * @brief Mandatory function, used to wait during an amount of time. It must be 745 | * filled as it's used into the API. 746 | * @param (VL53L7CX_Platform*) p_platform : Pointer of VL53L7CX platform 747 | * structure. 748 | * @param (uint32_t) TimeMs : Time to wait in ms. 749 | * @return (uint8_t) status : 0 if wait is finished. 750 | */ 751 | 752 | uint8_t WaitMs( 753 | VL53L7CX_Platform *p_platform, 754 | uint32_t TimeMs); 755 | 756 | protected: 757 | 758 | /* VL53L7CX Device */ 759 | VL53L7CX_Configuration _dev; 760 | VL53L7CX_Configuration *p_dev; 761 | }; 762 | 763 | #endif /* __VL53L7CX_CLASS_H */ 764 | -------------------------------------------------------------------------------- /src/vl53l7cx_platform.cpp: -------------------------------------------------------------------------------- 1 | /** 2 | ****************************************************************************** 3 | * @file vl53l7cx_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 "vl53l7cx_class.h" 40 | 41 | uint8_t VL53L7CX::RdByte( 42 | VL53L7CX_Platform *p_platform, 43 | uint16_t RegisterAddress, 44 | uint8_t *p_value) 45 | { 46 | uint8_t status = RdMulti(p_platform, RegisterAddress, p_value, 1); 47 | return status; 48 | } 49 | 50 | uint8_t VL53L7CX::WrByte( 51 | VL53L7CX_Platform *p_platform, 52 | uint16_t RegisterAddress, 53 | uint8_t value) 54 | { 55 | // Just use WrMulti but 1 byte 56 | uint8_t status = WrMulti(p_platform, RegisterAddress, &value, 1); 57 | return status; 58 | } 59 | 60 | uint8_t VL53L7CX::WrMulti( 61 | VL53L7CX_Platform *p_platform, 62 | uint16_t RegisterAddress, 63 | uint8_t *p_values, 64 | uint32_t size) 65 | { 66 | uint32_t i = 0; 67 | uint8_t buffer[2]; 68 | 69 | while (i < size) { 70 | // If still more than DEFAULT_I2C_BUFFER_LEN bytes to go, DEFAULT_I2C_BUFFER_LEN, 71 | // else the remaining number of bytes 72 | size_t current_write_size = (size - i > DEFAULT_I2C_BUFFER_LEN ? DEFAULT_I2C_BUFFER_LEN : size - i); 73 | 74 | p_platform->dev_i2c->beginTransmission((uint8_t)((p_platform->address >> 1) & 0x7F)); 75 | 76 | // Target register address for transfer 77 | buffer[0] = (uint8_t)((RegisterAddress + i) >> 8); 78 | buffer[1] = (uint8_t)((RegisterAddress + i) & 0xFF); 79 | p_platform->dev_i2c->write(buffer, 2); 80 | if (p_platform->dev_i2c->write(p_values + i, current_write_size) == 0) { 81 | return 1; 82 | } else { 83 | i += current_write_size; 84 | if (size - i) { 85 | 86 | // Flush buffer and send stop bit so we have compatibility also with ESP32 platforms 87 | p_platform->dev_i2c->endTransmission(true); 88 | 89 | } 90 | } 91 | } 92 | return p_platform->dev_i2c->endTransmission(true); 93 | } 94 | 95 | uint8_t VL53L7CX::RdMulti( 96 | VL53L7CX_Platform *p_platform, 97 | uint16_t RegisterAddress, 98 | uint8_t *p_values, 99 | uint32_t size) 100 | { 101 | int status = 0; 102 | uint8_t buffer[2]; 103 | 104 | // Loop until the port is transmitted correctly 105 | do { 106 | p_platform->dev_i2c->beginTransmission((uint8_t)((p_platform->address >> 1) & 0x7F)); 107 | 108 | // Target register address for transfer 109 | buffer[0] = (uint8_t)(RegisterAddress >> 8); 110 | buffer[1] = (uint8_t)(RegisterAddress & 0xFF); 111 | p_platform->dev_i2c->write(buffer, 2); 112 | 113 | status = p_platform->dev_i2c->endTransmission(false); 114 | 115 | // Fix for some STM32 boards 116 | // Reinitialize the i2c bus with the default parameters 117 | #ifdef ARDUINO_ARCH_STM32 118 | if (status) { 119 | p_platform->dev_i2c->end(); 120 | p_platform->dev_i2c->begin(); 121 | } 122 | #endif 123 | // End of fix 124 | 125 | } while (status != 0); 126 | uint32_t i = 0; 127 | if (size > DEFAULT_I2C_BUFFER_LEN) { 128 | while (i < size) { 129 | // If still more than DEFAULT_I2C_BUFFER_LEN bytes to go, DEFAULT_I2C_BUFFER_LEN, 130 | // else the remaining number of bytes 131 | uint8_t current_read_size = (size - i > DEFAULT_I2C_BUFFER_LEN ? DEFAULT_I2C_BUFFER_LEN : size - i); 132 | p_platform->dev_i2c->requestFrom(((uint8_t)((p_platform->address >> 1) & 0x7F)), 133 | current_read_size); 134 | while (p_platform->dev_i2c->available()) { 135 | p_values[i] = p_platform->dev_i2c->read(); 136 | i++; 137 | } 138 | } 139 | } else { 140 | p_platform->dev_i2c->requestFrom(((uint8_t)((p_platform->address >> 1) & 0x7F)), size); 141 | while (p_platform->dev_i2c->available()) { 142 | p_values[i] = p_platform->dev_i2c->read(); 143 | i++; 144 | } 145 | } 146 | 147 | 148 | return i != size; 149 | } 150 | 151 | void VL53L7CX::SwapBuffer( 152 | uint8_t *buffer, 153 | uint16_t size) 154 | { 155 | uint32_t i, tmp; 156 | 157 | /* Example of possible implementation using */ 158 | for (i = 0; i < size; i = i + 4) { 159 | tmp = ( 160 | buffer[i] << 24) 161 | | (buffer[i + 1] << 16) 162 | | (buffer[i + 2] << 8) 163 | | (buffer[i + 3]); 164 | 165 | memcpy(&(buffer[i]), &tmp, 4); 166 | } 167 | } 168 | 169 | uint8_t VL53L7CX::WaitMs( 170 | VL53L7CX_Platform *p_platform, 171 | uint32_t TimeMs) 172 | { 173 | (void)p_platform; 174 | delay(TimeMs); 175 | 176 | return 0; 177 | } 178 | -------------------------------------------------------------------------------- /src/vl53l7cx_platform.h: -------------------------------------------------------------------------------- 1 | /** 2 | ****************************************************************************** 3 | * @file vl53l7cx_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 _VL53L7CX_PLATFORM_H_ 39 | #define _VL53L7CX_PLATFORM_H_ 40 | #pragma once 41 | 42 | #include 43 | #include 44 | #include 45 | #include 46 | #include "vl53l7cx_platform_config.h" 47 | 48 | 49 | #ifndef DEFAULT_I2C_BUFFER_LEN 50 | #ifdef ARDUINO_SAM_DUE 51 | /* FIXME: It seems that an I2C buffer of BUFFER_LENGTH does not work on Arduino DUE. So, we need to decrease the size */ 52 | #define DEFAULT_I2C_BUFFER_LEN (BUFFER_LENGTH - 2) 53 | #else 54 | #ifdef BUFFER_LENGTH 55 | #define DEFAULT_I2C_BUFFER_LEN BUFFER_LENGTH 56 | #else 57 | #define DEFAULT_I2C_BUFFER_LEN 32 58 | #endif 59 | #endif 60 | #endif 61 | 62 | /** 63 | * @brief Structure VL53L7CX_Platform needs to be filled by the customer, 64 | * depending on his platform. At least, it contains the VL53L7CX I2C address. 65 | * Some additional fields can be added, as descriptors, or platform 66 | * dependencies. Anything added into this structure is visible into the platform 67 | * layer. 68 | */ 69 | 70 | typedef struct { 71 | uint16_t address; 72 | 73 | TwoWire *dev_i2c; 74 | 75 | int lpn_pin; 76 | 77 | int i2c_rst_pin; 78 | 79 | } VL53L7CX_Platform; 80 | 81 | #endif // _VL53L7CX_PLATFORM_H_ 82 | -------------------------------------------------------------------------------- /src/vl53l7cx_platform_config.h: -------------------------------------------------------------------------------- 1 | /** 2 | ****************************************************************************** 3 | * @file vl53l7cx_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 _VL53L7CX_PLATFORM_CONFIG_H_ 39 | #define _VL53L7CX_PLATFORM_CONFIG_H_ 40 | 41 | #if __has_include("vl53l7cx_platform_config_custom.h") 42 | #include "vl53l7cx_platform_config_custom.h" 43 | #else 44 | #include "vl53l7cx_platform_config_default.h" 45 | #endif 46 | 47 | #endif // _VL53L7CX_PLATFORM_CONFIG_H_ 48 | -------------------------------------------------------------------------------- /src/vl53l7cx_platform_config_default.h: -------------------------------------------------------------------------------- 1 | /** 2 | ****************************************************************************** 3 | * @file vl53l7cx_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 _VL53L7CX_PLATFORM_CONFIG_DEFAULT_H_ 39 | #define _VL53L7CX_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 VL53L7CX_NB_TARGET_PER_ZONE 55 | #define VL53L7CX_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 VL53L7CX_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 VL53L7CX_DISABLE_AMBIENT_PER_SPAD 74 | // #define VL53L7CX_DISABLE_NB_SPADS_ENABLED 75 | // #define VL53L7CX_DISABLE_NB_TARGET_DETECTED 76 | // #define VL53L7CX_DISABLE_SIGNAL_PER_SPAD 77 | // #define VL53L7CX_DISABLE_RANGE_SIGMA_MM 78 | // #define VL53L7CX_DISABLE_DISTANCE_MM 79 | // #define VL53L7CX_DISABLE_REFLECTANCE_PERCENT 80 | // #define VL53L7CX_DISABLE_TARGET_STATUS 81 | // #define VL53L7CX_DISABLE_MOTION_INDICATOR 82 | 83 | #endif // _VL53L7CX_PLATFORM_CONFIG_DEFAULT_H_ 84 | -------------------------------------------------------------------------------- /src/vl53l7cx_plugin_detection_thresholds.cpp: -------------------------------------------------------------------------------- 1 | /** 2 | ****************************************************************************** 3 | * @file vl53l7cx_plugin_detection_thresholds.cpp 4 | * @author STMicroelectronics 5 | * @version V1.0.0 6 | * @date 13 January 2023 7 | * @brief Implementation of the VL53L7CX APIs for thresholds detection. 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 | #include "vl53l7cx_class.h" 39 | 40 | uint8_t VL53L7CX::vl53l7cx_get_detection_thresholds_enable( 41 | uint8_t *p_enabled) 42 | { 43 | uint8_t status = VL53L7CX_STATUS_OK; 44 | 45 | status |= vl53l7cx_dci_read_data((uint8_t *)p_dev->temp_buffer, 46 | VL53L7CX_DCI_DET_THRESH_GLOBAL_CONFIG, 8); 47 | *p_enabled = p_dev->temp_buffer[0x1]; 48 | 49 | return status; 50 | } 51 | 52 | uint8_t VL53L7CX::vl53l7cx_set_detection_thresholds_enable( 53 | uint8_t enabled) 54 | { 55 | uint8_t tmp, status = VL53L7CX_STATUS_OK; 56 | uint8_t grp_global_config[] = {0x01, 0x00, 0x01, 0x00}; 57 | 58 | if (enabled == (uint8_t)1) { 59 | grp_global_config[0x01] = 0x01; 60 | tmp = 0x04; 61 | } else { 62 | grp_global_config[0x01] = 0x00; 63 | tmp = 0x0C; 64 | } 65 | 66 | /* Set global interrupt config */ 67 | status |= vl53l7cx_dci_replace_data(p_dev->temp_buffer, 68 | VL53L7CX_DCI_DET_THRESH_GLOBAL_CONFIG, 8, 69 | (uint8_t *)&grp_global_config, 4, 0x00); 70 | 71 | /* Update interrupt config */ 72 | status |= vl53l7cx_dci_replace_data(p_dev->temp_buffer, 73 | VL53L7CX_DCI_DET_THRESH_CONFIG, 20, 74 | (uint8_t *)&tmp, 1, 0x11); 75 | 76 | return status; 77 | } 78 | 79 | uint8_t VL53L7CX::vl53l7cx_get_detection_thresholds( 80 | VL53L7CX_DetectionThresholds *p_thresholds) 81 | { 82 | uint8_t i, status = VL53L7CX_STATUS_OK; 83 | 84 | /* Get thresholds configuration */ 85 | status |= vl53l7cx_dci_read_data((uint8_t *)p_thresholds, 86 | VL53L7CX_DCI_DET_THRESH_START, 87 | (uint16_t)VL53L7CX_NB_THRESHOLDS 88 | * (uint16_t)sizeof(VL53L7CX_DetectionThresholds)); 89 | 90 | for (i = 0; i < (uint8_t)VL53L7CX_NB_THRESHOLDS; i++) { 91 | switch (p_thresholds[i].measurement) { 92 | case VL53L7CX_DISTANCE_MM: 93 | p_thresholds[i].param_low_thresh /= 4; 94 | p_thresholds[i].param_high_thresh /= 4; 95 | break; 96 | case VL53L7CX_SIGNAL_PER_SPAD_KCPS: 97 | p_thresholds[i].param_low_thresh /= 2048; 98 | p_thresholds[i].param_high_thresh /= 2048; 99 | break; 100 | case VL53L7CX_RANGE_SIGMA_MM: 101 | p_thresholds[i].param_low_thresh /= 128; 102 | p_thresholds[i].param_high_thresh /= 128; 103 | break; 104 | case VL53L7CX_AMBIENT_PER_SPAD_KCPS: 105 | p_thresholds[i].param_low_thresh /= 2048; 106 | p_thresholds[i].param_high_thresh /= 2048; 107 | break; 108 | case VL53L7CX_NB_SPADS_ENABLED: 109 | p_thresholds[i].param_low_thresh /= 256; 110 | p_thresholds[i].param_high_thresh /= 256; 111 | break; 112 | case VL53L7CX_MOTION_INDICATOR: 113 | p_thresholds[i].param_low_thresh /= 65535; 114 | p_thresholds[i].param_high_thresh /= 65535; 115 | break; 116 | default: 117 | break; 118 | } 119 | } 120 | 121 | return status; 122 | } 123 | 124 | uint8_t VL53L7CX::vl53l7cx_set_detection_thresholds( 125 | VL53L7CX_DetectionThresholds *p_thresholds) 126 | { 127 | uint8_t i, status = VL53L7CX_STATUS_OK; 128 | uint8_t grp_valid_target_cfg[] = {0x05, 0x05, 0x05, 0x05, 129 | 0x05, 0x05, 0x05, 0x05 130 | }; 131 | 132 | for (i = 0; i < (uint8_t) VL53L7CX_NB_THRESHOLDS; i++) { 133 | switch (p_thresholds->measurement) { 134 | case VL53L7CX_DISTANCE_MM: 135 | p_thresholds[i].param_low_thresh *= 4; 136 | p_thresholds[i].param_high_thresh *= 4; 137 | break; 138 | case VL53L7CX_SIGNAL_PER_SPAD_KCPS: 139 | p_thresholds[i].param_low_thresh *= 2048; 140 | p_thresholds[i].param_high_thresh *= 2048; 141 | break; 142 | case VL53L7CX_RANGE_SIGMA_MM: 143 | p_thresholds[i].param_low_thresh *= 128; 144 | p_thresholds[i].param_high_thresh *= 128; 145 | break; 146 | case VL53L7CX_AMBIENT_PER_SPAD_KCPS: 147 | p_thresholds[i].param_low_thresh *= 2048; 148 | p_thresholds[i].param_high_thresh *= 2048; 149 | break; 150 | case VL53L7CX_NB_SPADS_ENABLED: 151 | p_thresholds[i].param_low_thresh *= 256; 152 | p_thresholds[i].param_high_thresh *= 256; 153 | break; 154 | case VL53L7CX_MOTION_INDICATOR: 155 | p_thresholds[i].param_low_thresh *= 65535; 156 | p_thresholds[i].param_high_thresh *= 65535; 157 | break; 158 | default: 159 | break; 160 | } 161 | } 162 | 163 | /* Set valid target list */ 164 | status |= vl53l7cx_dci_write_data((uint8_t *)grp_valid_target_cfg, 165 | VL53L7CX_DCI_DET_THRESH_VALID_STATUS, 166 | (uint16_t)sizeof(grp_valid_target_cfg)); 167 | 168 | /* Set thresholds configuration */ 169 | status |= vl53l7cx_dci_write_data((uint8_t *)p_thresholds, 170 | VL53L7CX_DCI_DET_THRESH_START, 171 | (uint16_t)(VL53L7CX_NB_THRESHOLDS 172 | * sizeof(VL53L7CX_DetectionThresholds))); 173 | 174 | return status; 175 | } 176 | -------------------------------------------------------------------------------- /src/vl53l7cx_plugin_detection_thresholds.h: -------------------------------------------------------------------------------- 1 | /** 2 | ****************************************************************************** 3 | * @file vl53l7cx_plugin_detection_thresholds.h 4 | * @author STMicroelectronics 5 | * @version V1.0.0 6 | * @date 13 January 2023 7 | * @brief Header file for the VL53L7CX thresholds detection 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 VL53L7CX_PLUGIN_DETECTION_THRESHOLDS_H_ 39 | #define VL53L7CX_PLUGIN_DETECTION_THRESHOLDS_H_ 40 | 41 | #include "vl53l7cx_class.h" 42 | 43 | /** 44 | * @brief Macro VL53L7CX_NB_THRESHOLDS indicates the number of checkers. This 45 | * value cannot be changed. 46 | */ 47 | 48 | #define VL53L7CX_NB_THRESHOLDS ((uint8_t)64U) 49 | 50 | /** 51 | * @brief Inner Macro for API. Not for user, only for development. 52 | */ 53 | 54 | #define VL53L7CX_DCI_DET_THRESH_CONFIG ((uint16_t)0x5488U) 55 | #define VL53L7CX_DCI_DET_THRESH_GLOBAL_CONFIG ((uint16_t)0xB6E0U) 56 | #define VL53L7CX_DCI_DET_THRESH_START ((uint16_t)0xB6E8U) 57 | #define VL53L7CX_DCI_DET_THRESH_VALID_STATUS ((uint16_t)0xB9F0U) 58 | 59 | /** 60 | * @brief Macro VL53L7CX_LAST_THRESHOLD is used to indicate the end of checkers 61 | * programming. 62 | */ 63 | 64 | #define VL53L7CX_LAST_THRESHOLD ((uint8_t)128U) 65 | 66 | /** 67 | * @brief The following macro are used to define the 'param_type' of a checker. 68 | * They indicate what is the measurement to catch. 69 | */ 70 | 71 | #define VL53L7CX_DISTANCE_MM ((uint8_t)1U) 72 | #define VL53L7CX_SIGNAL_PER_SPAD_KCPS ((uint8_t)2U) 73 | #define VL53L7CX_RANGE_SIGMA_MM ((uint8_t)4U) 74 | #define VL53L7CX_AMBIENT_PER_SPAD_KCPS ((uint8_t)8U) 75 | #define VL53L7CX_NB_TARGET_DETECTED ((uint8_t)9U) 76 | #define VL53L7CX_TARGET_STATUS ((uint8_t)12U) 77 | #define VL53L7CX_NB_SPADS_ENABLED ((uint8_t)13U) 78 | #define VL53L7CX_MOTION_INDICATOR ((uint8_t)19U) 79 | 80 | /** 81 | * @brief The following macro are used to define the 'type' of a checker. 82 | * They indicate the window of measurements, defined by low and a high 83 | * thresholds. 84 | */ 85 | 86 | #define VL53L7CX_IN_WINDOW ((uint8_t)0U) 87 | #define VL53L7CX_OUT_OF_WINDOW ((uint8_t)1U) 88 | #define VL53L7CX_LESS_THAN_EQUAL_MIN_CHECKER ((uint8_t)2U) 89 | #define VL53L7CX_GREATER_THAN_MAX_CHECKER ((uint8_t)3U) 90 | #define VL53L7CX_EQUAL_MIN_CHECKER ((uint8_t)4U) 91 | #define VL53L7CX_NOT_EQUAL_MIN_CHECKER ((uint8_t)5U) 92 | 93 | /** 94 | * @brief The following macro are used to define multiple checkers in the same 95 | * zone, using operators. Please note that the first checker MUST always be a OR 96 | * operation. 97 | */ 98 | 99 | #define VL53L7CX_OPERATION_NONE ((uint8_t)0U) 100 | #define VL53L7CX_OPERATION_OR ((uint8_t)0U) 101 | #define VL53L7CX_OPERATION_AND ((uint8_t)2U) 102 | 103 | /** 104 | * @brief Structure VL53L7CX_DetectionThresholds contains a single threshold. 105 | * This structure is never used alone, it must be used as an array of 64 106 | * thresholds (defined by macro VL53L7CX_NB_THRESHOLDS). 107 | */ 108 | 109 | typedef struct { 110 | 111 | /* Low threshold */ 112 | int32_t param_low_thresh; 113 | /* High threshold */ 114 | int32_t param_high_thresh; 115 | /* Measurement to catch (VL53L7CX_MEDIAN_RANGE_MM,...)*/ 116 | uint8_t measurement; 117 | /* Windows type (VL53L7CX_IN_WINDOW, VL53L7CX_OUT_WINDOW, ...) */ 118 | uint8_t type; 119 | /* Zone id. Please read VL53L5 user manual to find the zone id.Set macro 120 | * VL53L7CX_LAST_THRESHOLD to indicates the end of checkers */ 121 | uint8_t zone_num; 122 | /* Mathematics operation (AND/OR). The first threshold is always OR.*/ 123 | uint8_t mathematic_operation; 124 | } VL53L7CX_DetectionThresholds; 125 | 126 | 127 | #endif /* VL53L7CX_PLUGIN_DETECTION_THRESHOLDS_H_ */ 128 | -------------------------------------------------------------------------------- /src/vl53l7cx_plugin_motion_indicator.cpp: -------------------------------------------------------------------------------- 1 | /** 2 | ****************************************************************************** 3 | * @file vl53l7cx_plugin_motion_indicator.cpp 4 | * @author STMicroelectronics 5 | * @version V1.0.0 6 | * @date 13 January 2023 7 | * @brief Implementation of the VL53L7CX APIs for motion indicator. 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 | #include 39 | #include "vl53l7cx_class.h" 40 | 41 | uint8_t VL53L7CX::vl53l7cx_motion_indicator_init( 42 | VL53L7CX_Motion_Configuration *p_motion_config, 43 | uint8_t resolution) 44 | { 45 | uint8_t status = VL53L7CX_STATUS_OK; 46 | 47 | (void)memset(p_motion_config, 0, sizeof(VL53L7CX_Motion_Configuration)); 48 | 49 | p_motion_config->ref_bin_offset = 13633; 50 | p_motion_config->detection_threshold = 2883584; 51 | p_motion_config->extra_noise_sigma = 0; 52 | p_motion_config->null_den_clip_value = 0; 53 | p_motion_config->mem_update_mode = 6; 54 | p_motion_config->mem_update_choice = 2; 55 | p_motion_config->sum_span = 4; 56 | p_motion_config->feature_length = 9; 57 | p_motion_config->nb_of_aggregates = 16; 58 | p_motion_config->nb_of_temporal_accumulations = 16; 59 | p_motion_config->min_nb_for_global_detection = 1; 60 | p_motion_config->global_indicator_format_1 = 8; 61 | p_motion_config->global_indicator_format_2 = 0; 62 | p_motion_config->spare_1 = 0; 63 | p_motion_config->spare_2 = 0; 64 | p_motion_config->spare_3 = 0; 65 | 66 | status |= vl53l7cx_motion_indicator_set_resolution( 67 | p_motion_config, resolution); 68 | 69 | return status; 70 | } 71 | 72 | uint8_t VL53L7CX::vl53l7cx_motion_indicator_set_distance_motion( 73 | VL53L7CX_Motion_Configuration *p_motion_config, 74 | uint16_t distance_min_mm, 75 | uint16_t distance_max_mm) 76 | { 77 | uint8_t status = VL53L7CX_STATUS_OK; 78 | float_t tmp; 79 | 80 | if (((distance_max_mm - distance_min_mm) > (uint16_t)1500) 81 | || (distance_min_mm < (uint16_t)400) 82 | || (distance_max_mm > (uint16_t)4000)) { 83 | status |= VL53L7CX_STATUS_INVALID_PARAM; 84 | } else { 85 | tmp = (float_t)((((float_t)distance_min_mm / (float_t)37.5348) 86 | - (float_t)4.0) * (float_t)2048.5); 87 | p_motion_config->ref_bin_offset = (int32_t)tmp; 88 | 89 | tmp = (float_t)((((((float_t)distance_max_mm - 90 | (float_t)distance_min_mm) / (float_t)10.0) + (float_t)30.02784) 91 | / ((float_t)15.01392)) + (float_t)0.5); 92 | p_motion_config->feature_length = (uint8_t)tmp; 93 | 94 | status |= vl53l7cx_dci_write_data( 95 | (uint8_t *)(p_motion_config), 96 | VL53L7CX_DCI_MOTION_DETECTOR_CFG, 97 | (uint16_t)sizeof(*p_motion_config)); 98 | } 99 | 100 | return status; 101 | } 102 | 103 | uint8_t VL53L7CX::vl53l7cx_motion_indicator_set_resolution( 104 | VL53L7CX_Motion_Configuration *p_motion_config, 105 | uint8_t resolution) 106 | { 107 | uint8_t i, status = VL53L7CX_STATUS_OK; 108 | 109 | switch (resolution) { 110 | case VL53L7CX_RESOLUTION_4X4: 111 | for (i = 0; i < (uint8_t)VL53L7CX_RESOLUTION_4X4; i++) { 112 | p_motion_config->map_id[i] = (int8_t)i; 113 | } 114 | (void)memset(p_motion_config->map_id + 16, -1, 48); 115 | break; 116 | 117 | case VL53L7CX_RESOLUTION_8X8: 118 | for (i = 0; i < (uint8_t)VL53L7CX_RESOLUTION_8X8; i++) { 119 | p_motion_config->map_id[i] = (int8_t)((((int8_t) 120 | i % 8) / 2) + (4 * ((int8_t)i / 16))); 121 | } 122 | break; 123 | 124 | default: 125 | status |= VL53L7CX_STATUS_ERROR; 126 | break; 127 | } 128 | 129 | if (status != (uint8_t)0) { 130 | status |= vl53l7cx_dci_write_data( 131 | (uint8_t *)(p_motion_config), 132 | VL53L7CX_DCI_MOTION_DETECTOR_CFG, 133 | (uint16_t)sizeof(*p_motion_config)); 134 | } 135 | 136 | return status; 137 | } 138 | -------------------------------------------------------------------------------- /src/vl53l7cx_plugin_motion_indicator.h: -------------------------------------------------------------------------------- 1 | /** 2 | ****************************************************************************** 3 | * @file vl53l7cx_plugin_motion_indicator.h 4 | * @author STMicroelectronics 5 | * @version V1.0.0 6 | * @date 13 January 2023 7 | * @brief Header file for the VL53L7CX motion indicator 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 VL53L7CX_PLUGIN_MOTION_INDICATOR_H_ 39 | #define VL53L7CX_PLUGIN_MOTION_INDICATOR_H_ 40 | 41 | #include "vl53l7cx_class.h" 42 | 43 | /** 44 | * @brief Motion indicator internal configuration structure. 45 | */ 46 | 47 | typedef struct { 48 | int32_t ref_bin_offset; 49 | uint32_t detection_threshold; 50 | uint32_t extra_noise_sigma; 51 | uint32_t null_den_clip_value; 52 | uint8_t mem_update_mode; 53 | uint8_t mem_update_choice; 54 | uint8_t sum_span; 55 | uint8_t feature_length; 56 | uint8_t nb_of_aggregates; 57 | uint8_t nb_of_temporal_accumulations; 58 | uint8_t min_nb_for_global_detection; 59 | uint8_t global_indicator_format_1; 60 | uint8_t global_indicator_format_2; 61 | uint8_t spare_1; 62 | uint8_t spare_2; 63 | uint8_t spare_3; 64 | int8_t map_id[64]; 65 | uint8_t indicator_format_1[32]; 66 | uint8_t indicator_format_2[32]; 67 | } VL53L7CX_Motion_Configuration; 68 | 69 | #endif /* VL53L7CX_PLUGIN_MOTION_INDICATOR_H_ */ 70 | -------------------------------------------------------------------------------- /src/vl53l7cx_plugin_xtalk.cpp: -------------------------------------------------------------------------------- 1 | /** 2 | ****************************************************************************** 3 | * @file vl53l7cx_plugin_xtalk.cpp 4 | * @author STMicroelectronics 5 | * @version V1.0.0 6 | * @date 13 January 2023 7 | * @brief Implementation of the VL53L7CX APIs for xtalk calibration. 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 | #include "vl53l7cx_class.h" 39 | 40 | /* 41 | * Inner function, not available outside this file. This function is used to 42 | * wait for an answer from VL53L5 sensor. 43 | */ 44 | 45 | uint8_t VL53L7CX::_vl53l7cx_poll_for_answer_xtalk( 46 | uint16_t address, 47 | uint8_t expected_value) 48 | { 49 | uint8_t status = VL53L7CX_STATUS_OK; 50 | uint8_t timeout = 0; 51 | 52 | do { 53 | status |= RdMulti(&(p_dev->platform), 54 | address, p_dev->temp_buffer, 4); 55 | status |= WaitMs(&(p_dev->platform), 10); 56 | 57 | /* 2s timeout or FW error*/ 58 | if ((timeout >= (uint8_t)200) 59 | || (p_dev->temp_buffer[2] >= (uint8_t) 0x7f)) { 60 | status |= VL53L7CX_MCU_ERROR; 61 | break; 62 | } else { 63 | timeout++; 64 | } 65 | } while ((p_dev->temp_buffer[0x1]) != expected_value); 66 | 67 | return status; 68 | } 69 | 70 | /* 71 | * Inner function, not available outside this file. This function is used to 72 | * program the output using the macro defined into the 'platform.h' file. 73 | */ 74 | 75 | uint8_t VL53L7CX::_vl53l7cx_program_output_config() 76 | { 77 | uint8_t resolution, status = VL53L7CX_STATUS_OK; 78 | uint32_t i; 79 | union Block_header *bh_ptr; 80 | uint32_t header_config[2] = {0, 0}; 81 | 82 | status |= vl53l7cx_get_resolution(&resolution); 83 | p_dev->data_read_size = 0; 84 | 85 | /* Enable mandatory output (meta and common data) */ 86 | uint32_t output_bh_enable[] = { 87 | 0x0001FFFFU, 88 | 0x00000000U, 89 | 0x00000000U, 90 | 0xC0000000U 91 | }; 92 | 93 | /* Send addresses of possible output */ 94 | uint32_t output[] = { 95 | 0x0000000DU, 96 | 0x54000040U, 97 | 0x9FD800C0U, 98 | 0x9FE40140U, 99 | 0x9FF80040U, 100 | 0x9FFC0404U, 101 | 0xA0FC0100U, 102 | 0xA10C0100U, 103 | 0xA11C00C0U, 104 | 0xA1280902U, 105 | 0xA2480040U, 106 | 0xA24C0081U, 107 | 0xA2540081U, 108 | 0xA25C0081U, 109 | 0xA2640081U, 110 | 0xA26C0084U, 111 | 0xA28C0082U 112 | }; 113 | 114 | /* Update data size */ 115 | for (i = 0; i < (uint32_t)(sizeof(output) / sizeof(uint32_t)); i++) { 116 | if ((output[i] == (uint8_t)0) 117 | || ((output_bh_enable[i / (uint32_t)32] 118 | & ((uint32_t)1 << (i % (uint32_t)32))) == (uint32_t)0)) { 119 | continue; 120 | } 121 | 122 | bh_ptr = (union Block_header *) & (output[i]); 123 | if (((uint8_t)bh_ptr->type >= (uint8_t)0x1) 124 | && ((uint8_t)bh_ptr->type < (uint8_t)0x0d)) { 125 | if ((bh_ptr->idx >= (uint16_t)0x54d0) 126 | && (bh_ptr->idx < (uint16_t)(0x54d0 + 960))) { 127 | bh_ptr->size = resolution; 128 | } else { 129 | bh_ptr->size = (uint8_t)(resolution 130 | * (uint8_t)VL53L7CX_NB_TARGET_PER_ZONE); 131 | } 132 | 133 | 134 | p_dev->data_read_size += bh_ptr->type * bh_ptr->size; 135 | } else { 136 | p_dev->data_read_size += bh_ptr->size; 137 | } 138 | p_dev->data_read_size += (uint32_t)4; 139 | } 140 | p_dev->data_read_size += (uint32_t)24; 141 | 142 | status |= vl53l7cx_dci_write_data( 143 | (uint8_t *) & (output), 144 | VL53L7CX_DCI_OUTPUT_LIST, (uint16_t)sizeof(output)); 145 | 146 | header_config[0] = p_dev->data_read_size; 147 | header_config[1] = i + (uint32_t)1; 148 | 149 | status |= vl53l7cx_dci_write_data( 150 | (uint8_t *) & (header_config), VL53L7CX_DCI_OUTPUT_CONFIG, 151 | (uint16_t)sizeof(header_config)); 152 | 153 | status |= vl53l7cx_dci_write_data((uint8_t *) & (output_bh_enable), 154 | VL53L7CX_DCI_OUTPUT_ENABLES, 155 | (uint16_t)sizeof(output_bh_enable)); 156 | 157 | return status; 158 | } 159 | 160 | uint8_t VL53L7CX::vl53l7cx_calibrate_xtalk( 161 | uint16_t reflectance_percent, 162 | uint8_t nb_samples, 163 | uint16_t distance_mm) 164 | { 165 | uint16_t timeout = 0; 166 | uint8_t cmd[] = {0x00, 0x03, 0x00, 0x00}; 167 | uint8_t footer[] = {0x00, 0x00, 0x00, 0x0F, 0x00, 0x01, 0x03, 0x04}; 168 | uint8_t continue_loop = 1, status = VL53L7CX_STATUS_OK; 169 | 170 | uint8_t resolution, frequency, target_order, sharp_prct, ranging_mode; 171 | uint32_t integration_time_ms, xtalk_margin; 172 | 173 | uint16_t reflectance = reflectance_percent; 174 | uint8_t samples = nb_samples; 175 | uint16_t distance = distance_mm; 176 | 177 | /* Get initial configuration */ 178 | status |= vl53l7cx_get_resolution(&resolution); 179 | status |= vl53l7cx_get_ranging_frequency_hz(&frequency); 180 | status |= vl53l7cx_get_integration_time_ms(&integration_time_ms); 181 | status |= vl53l7cx_get_sharpener_percent(&sharp_prct); 182 | status |= vl53l7cx_get_target_order(&target_order); 183 | status |= vl53l7cx_get_xtalk_margin(&xtalk_margin); 184 | status |= vl53l7cx_get_ranging_mode(&ranging_mode); 185 | 186 | /* Check input arguments validity */ 187 | if (((reflectance < (uint16_t)1) || (reflectance > (uint16_t)99)) 188 | || ((distance < (uint16_t)600) || (distance > (uint16_t)3000)) 189 | || ((samples < (uint8_t)1) || (samples > (uint8_t)16))) { 190 | status |= VL53L7CX_STATUS_INVALID_PARAM; 191 | } else { 192 | status |= vl53l7cx_set_resolution( 193 | VL53L7CX_RESOLUTION_8X8); 194 | 195 | /* Send Xtalk calibration buffer */ 196 | (void)memcpy(p_dev->temp_buffer, VL53L7CX_CALIBRATE_XTALK, 197 | sizeof(VL53L7CX_CALIBRATE_XTALK)); 198 | status |= WrMulti(&(p_dev->platform), 0x2c28, 199 | p_dev->temp_buffer, 200 | (uint16_t)sizeof(VL53L7CX_CALIBRATE_XTALK)); 201 | status |= _vl53l7cx_poll_for_answer_xtalk( 202 | VL53L7CX_UI_CMD_STATUS, 0x3); 203 | 204 | /* Format input argument */ 205 | reflectance = reflectance * (uint16_t)16; 206 | distance = distance * (uint16_t)4; 207 | 208 | /* Update required fields */ 209 | status |= vl53l7cx_dci_replace_data(p_dev->temp_buffer, 210 | VL53L7CX_DCI_CAL_CFG, 8, 211 | (uint8_t *)&distance, 2, 0x00); 212 | 213 | status |= vl53l7cx_dci_replace_data(p_dev->temp_buffer, 214 | VL53L7CX_DCI_CAL_CFG, 8, 215 | (uint8_t *)&reflectance, 2, 0x02); 216 | 217 | status |= vl53l7cx_dci_replace_data(p_dev->temp_buffer, 218 | VL53L7CX_DCI_CAL_CFG, 8, 219 | (uint8_t *)&samples, 1, 0x04); 220 | 221 | /* Program output for Xtalk calibration */ 222 | status |= _vl53l7cx_program_output_config(); 223 | 224 | /* Start ranging session */ 225 | status |= WrMulti(&(p_dev->platform), 226 | VL53L7CX_UI_CMD_END - (uint16_t)(4 - 1), 227 | (uint8_t *)cmd, sizeof(cmd)); 228 | status |= _vl53l7cx_poll_for_answer_xtalk( 229 | VL53L7CX_UI_CMD_STATUS, 0x3); 230 | 231 | /* Wait for end of calibration */ 232 | do { 233 | status |= RdMulti(&(p_dev->platform), 234 | 0x0, p_dev->temp_buffer, 4); 235 | 236 | if (p_dev->temp_buffer[0] != VL53L7CX_STATUS_ERROR) { 237 | /* Coverglass too good for Xtalk calibration */ 238 | if ((p_dev->temp_buffer[2] >= (uint8_t)0x7f) && 239 | (((uint16_t)(p_dev->temp_buffer[3] & 240 | (uint16_t)0x80) >> 7) == (uint16_t)1)) { 241 | (void)memcpy(p_dev->xtalk_data, 242 | p_dev->default_xtalk, 243 | VL53L7CX_XTALK_BUFFER_SIZE); 244 | } 245 | continue_loop = (uint8_t)0; 246 | } else if (timeout >= (uint16_t)400) { 247 | status |= VL53L7CX_STATUS_ERROR; 248 | continue_loop = (uint8_t)0; 249 | } else { 250 | timeout++; 251 | status |= WaitMs(&(p_dev->platform), 50); 252 | } 253 | 254 | } while (continue_loop == (uint8_t)1); 255 | } 256 | 257 | /* Save Xtalk data into the Xtalk buffer */ 258 | (void)memcpy(p_dev->temp_buffer, VL53L7CX_GET_XTALK_CMD, 259 | sizeof(VL53L7CX_GET_XTALK_CMD)); 260 | status |= WrMulti(&(p_dev->platform), 0x2fb8, 261 | p_dev->temp_buffer, 262 | (uint16_t)sizeof(VL53L7CX_GET_XTALK_CMD)); 263 | status |= _vl53l7cx_poll_for_answer_xtalk(VL53L7CX_UI_CMD_STATUS, 0x03); 264 | status |= RdMulti(&(p_dev->platform), VL53L7CX_UI_CMD_START, 265 | p_dev->temp_buffer, 266 | VL53L7CX_XTALK_BUFFER_SIZE + (uint16_t)4); 267 | 268 | (void)memcpy(&(p_dev->xtalk_data[0]), &(p_dev->temp_buffer[8]), 269 | VL53L7CX_XTALK_BUFFER_SIZE - (uint16_t)8); 270 | (void)memcpy(&(p_dev->xtalk_data[VL53L7CX_XTALK_BUFFER_SIZE 271 | - (uint16_t)8]), footer, sizeof(footer)); 272 | 273 | /* Reset default buffer */ 274 | status |= WrMulti(&(p_dev->platform), 0x2c34, 275 | p_dev->default_configuration, 276 | VL53L7CX_CONFIGURATION_SIZE); 277 | status |= _vl53l7cx_poll_for_answer_xtalk(VL53L7CX_UI_CMD_STATUS, 0x03); 278 | 279 | /* Reset initial configuration */ 280 | status |= vl53l7cx_set_resolution(resolution); 281 | status |= vl53l7cx_set_ranging_frequency_hz(frequency); 282 | status |= vl53l7cx_set_integration_time_ms(integration_time_ms); 283 | status |= vl53l7cx_set_sharpener_percent(sharp_prct); 284 | status |= vl53l7cx_set_target_order(target_order); 285 | status |= vl53l7cx_set_xtalk_margin(xtalk_margin); 286 | status |= vl53l7cx_set_ranging_mode(ranging_mode); 287 | 288 | return status; 289 | } 290 | 291 | uint8_t VL53L7CX::vl53l7cx_get_caldata_xtalk(uint8_t *p_xtalk_data) 292 | { 293 | uint8_t status = VL53L7CX_STATUS_OK, resolution; 294 | uint8_t footer[] = {0x00, 0x00, 0x00, 0x0F, 0x00, 0x01, 0x03, 0x04}; 295 | 296 | status |= vl53l7cx_get_resolution(&resolution); 297 | status |= vl53l7cx_set_resolution(VL53L7CX_RESOLUTION_8X8); 298 | 299 | (void)memcpy(p_dev->temp_buffer, VL53L7CX_GET_XTALK_CMD, 300 | sizeof(VL53L7CX_GET_XTALK_CMD)); 301 | status |= WrMulti(&(p_dev->platform), 0x2fb8, 302 | p_dev->temp_buffer, sizeof(VL53L7CX_GET_XTALK_CMD)); 303 | status |= _vl53l7cx_poll_for_answer_xtalk(VL53L7CX_UI_CMD_STATUS, 0x03); 304 | status |= RdMulti(&(p_dev->platform), VL53L7CX_UI_CMD_START, 305 | p_dev->temp_buffer, 306 | VL53L7CX_XTALK_BUFFER_SIZE + (uint16_t)4); 307 | 308 | (void)memcpy(&(p_xtalk_data[0]), &(p_dev->temp_buffer[8]), 309 | VL53L7CX_XTALK_BUFFER_SIZE - (uint16_t)8); 310 | (void)memcpy(&(p_xtalk_data[VL53L7CX_XTALK_BUFFER_SIZE - (uint16_t)8]), 311 | footer, sizeof(footer)); 312 | 313 | status |= vl53l7cx_set_resolution(resolution); 314 | 315 | return status; 316 | } 317 | 318 | uint8_t VL53L7CX::vl53l7cx_set_caldata_xtalk(uint8_t *p_xtalk_data) 319 | { 320 | uint8_t resolution, status = VL53L7CX_STATUS_OK; 321 | 322 | status |= vl53l7cx_get_resolution(&resolution); 323 | (void)memcpy(p_dev->xtalk_data, p_xtalk_data, VL53L7CX_XTALK_BUFFER_SIZE); 324 | status |= vl53l7cx_set_resolution(resolution); 325 | 326 | return status; 327 | } 328 | 329 | uint8_t VL53L7CX::vl53l7cx_get_xtalk_margin(uint32_t *p_xtalk_margin) 330 | { 331 | uint8_t status = VL53L7CX_STATUS_OK; 332 | 333 | status |= vl53l7cx_dci_read_data((uint8_t *)p_dev->temp_buffer, 334 | VL53L7CX_DCI_XTALK_CFG, 16); 335 | 336 | (void)memcpy(p_xtalk_margin, p_dev->temp_buffer, 4); 337 | *p_xtalk_margin = *p_xtalk_margin / (uint32_t)2048; 338 | 339 | return status; 340 | } 341 | 342 | uint8_t VL53L7CX::vl53l7cx_set_xtalk_margin(uint32_t xtalk_margin) 343 | { 344 | uint8_t status = VL53L7CX_STATUS_OK; 345 | uint32_t margin_kcps = xtalk_margin; 346 | 347 | if (margin_kcps > (uint32_t)10000) { 348 | status |= VL53L7CX_STATUS_INVALID_PARAM; 349 | } else { 350 | margin_kcps = margin_kcps * (uint32_t)2048; 351 | status |= vl53l7cx_dci_replace_data(p_dev->temp_buffer, 352 | VL53L7CX_DCI_XTALK_CFG, 16, 353 | (uint8_t *)&margin_kcps, 4, 0x00); 354 | } 355 | 356 | return status; 357 | } 358 | -------------------------------------------------------------------------------- /src/vl53l7cx_plugin_xtalk.h: -------------------------------------------------------------------------------- 1 | /** 2 | ****************************************************************************** 3 | * @file vl53l7cx_plugin_xtalk.h 4 | * @author STMicroelectronics 5 | * @version V1.0.0 6 | * @date 13 January 2023 7 | * @brief Header file for the VL53L7CX xtalk 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 VL53L7CX_PLUGIN_XTALK_H_ 39 | #define VL53L7CX_PLUGIN_XTALK_H_ 40 | 41 | #include "vl53l7cx_class.h" 42 | 43 | /** 44 | * @brief Inner internal number of targets. 45 | */ 46 | 47 | #if VL53L7CX_NB_TARGET_PER_ZONE == 1 48 | #define VL53L7CX_FW_NBTAR_XTALK 2 49 | #else 50 | #define VL53L7CX_FW_NBTAR_XTALK VL53L7CX_NB_TARGET_PER_ZONE 51 | #endif 52 | 53 | /** 54 | * @brief Inner Macro for plugin. Not for user, only for development. 55 | */ 56 | 57 | #define VL53L7CX_DCI_CAL_CFG ((uint16_t)0x5470U) 58 | #define VL53L7CX_DCI_XTALK_CFG ((uint16_t)0xAD94U) 59 | 60 | /** 61 | * @brief Command used to get Xtalk calibration data 62 | */ 63 | 64 | static const uint8_t VL53L7CX_GET_XTALK_CMD[] = { 65 | 0x54, 0x00, 0x00, 0x40, 66 | 0x9F, 0xD8, 0x00, 0xC0, 67 | 0x9F, 0xE4, 0x01, 0x40, 68 | 0x9F, 0xF8, 0x00, 0x40, 69 | 0x9F, 0xFC, 0x04, 0x04, 70 | 0xA0, 0xFC, 0x01, 0x00, 71 | 0xA1, 0x0C, 0x01, 0x00, 72 | 0xA1, 0x1C, 0x00, 0xC0, 73 | 0xA1, 0x28, 0x09, 0x02, 74 | 0xA2, 0x48, 0x00, 0x40, 75 | 0xA2, 0x4C, 0x00, 0x81, 76 | 0xA2, 0x54, 0x00, 0x81, 77 | 0xA2, 0x5C, 0x00, 0x81, 78 | 0xA2, 0x64, 0x00, 0x81, 79 | 0xA2, 0x6C, 0x00, 0x84, 80 | 0xA2, 0x8C, 0x00, 0x82, 81 | 0x00, 0x00, 0x00, 0x0F, 82 | 0x07, 0x02, 0x00, 0x44 83 | }; 84 | 85 | /** 86 | * @brief Command used to get run Xtalk calibration 87 | */ 88 | 89 | static const uint8_t VL53L7CX_CALIBRATE_XTALK[] = { 90 | 0x54, 0x50, 0x00, 0x80, 91 | 0x00, 0x04, 0x08, 0x08, 92 | 0x00, 0x00, 0x04, 0x04, 93 | 0xAD, 0x30, 0x00, 0x80, 94 | 0x03, 0x01, 0x06, 0x03, 95 | 0x00, 0x00, 0x01, 0x00, 96 | 0xAD, 0x38, 0x01, 0x00, 97 | 0x01, 0xE0, 0x01, 0x40, 98 | 0x00, 0x10, 0x00, 0x10, 99 | 0x01, 0x00, 0x01, 0x00, 100 | 0x00, 0x00, 0x00, 0x01, 101 | 0x54, 0x58, 0x00, 0x40, 102 | 0x04, 0x1A, 0x02, 0x00, 103 | 0x54, 0x5C, 0x01, 0x40, 104 | 0x00, 0x01, 0x00, 0x51, 105 | 0x00, 0x00, 0x0F, 0xA0, 106 | 0x0F, 0xA0, 0x03, 0xE8, 107 | 0x02, 0x80, 0x1F, 0x40, 108 | 0x00, 0x00, 0x05, 0x00, 109 | 0x54, 0x70, 0x00, 0x80, 110 | 0x03, 0x20, 0x03, 0x20, 111 | 0x00, 0x00, 0x00, 0x08, 112 | 0x54, 0x78, 0x01, 0x00, 113 | 0x01, 0x1B, 0x00, 0x21, 114 | 0x00, 0x33, 0x00, 0x00, 115 | 0x02, 0x00, 0x00, 0x01, 116 | 0x04, 0x01, 0x08, VL53L7CX_FW_NBTAR_XTALK, 117 | 0x54, 0x88, 0x01, 0x40, 118 | 0x00, 0x00, 0x00, 0x00, 119 | 0x00, 0x00, 0x00, 0x00, 120 | 0x00, 0x00, 0x00, 0x00, 121 | 0x00, 0x00, 0x00, 0x00, 122 | 0x00, 0x00, 0x08, 0x00, 123 | 0xAD, 0x48, 0x01, 0x00, 124 | 0x01, 0xF4, 0x00, 0x00, 125 | 0x03, 0x06, 0x00, 0x10, 126 | 0x08, 0x08, 0x08, 0x08, 127 | 0x00, 0x00, 0x00, 0x08, 128 | 0xAD, 0x60, 0x01, 0x00, 129 | 0x00, 0x00, 0x00, 0x80, 130 | 0x00, 0x00, 0x00, 0x00, 131 | 0x20, 0x1F, 0x01, 0xF4, 132 | 0x00, 0x00, 0x1D, 0x0A, 133 | 0xAD, 0x70, 0x00, 0x80, 134 | 0x08, 0x00, 0x1F, 0x40, 135 | 0x00, 0x00, 0x00, 0x01, 136 | 0xAD, 0x78, 0x00, 0x80, 137 | 0x00, 0xA0, 0x03, 0x20, 138 | 0x00, 0x01, 0x01, 0x90, 139 | 0xAD, 0x80, 0x00, 0x40, 140 | 0x00, 0x00, 0x28, 0x00, 141 | 0xAD, 0x84, 0x00, 0x80, 142 | 0x00, 0x00, 0x32, 0x00, 143 | 0x03, 0x20, 0x00, 0x00, 144 | 0xAD, 0x8C, 0x00, 0x80, 145 | 0x02, 0x58, 0xFF, 0x38, 146 | 0x00, 0x00, 0x00, 0x0C, 147 | 0xAD, 0x94, 0x01, 0x00, 148 | 0x00, 0x01, 0x90, 0x00, 149 | 0xFF, 0xFF, 0xFC, 0x00, 150 | 0x00, 0x00, 0x04, 0x00, 151 | 0x00, 0x00, 0x01, 0x00, 152 | 0xAD, 0xA4, 0x00, 0xC0, 153 | 0x04, 0x80, 0x06, 0x1A, 154 | 0x00, 0x80, 0x05, 0x80, 155 | 0x00, 0x00, 0x01, 0x06, 156 | 0xAD, 0xB0, 0x00, 0xC0, 157 | 0x04, 0x80, 0x06, 0x1A, 158 | 0x19, 0x00, 0x05, 0x80, 159 | 0x00, 0x00, 0x01, 0x90, 160 | 0xAD, 0xBC, 0x04, 0x40, 161 | 0x00, 0x00, 0x00, 0x00, 162 | 0x00, 0x00, 0x00, 0x00, 163 | 0x00, 0x12, 0x00, 0x25, 164 | 0x00, 0x00, 0x00, 0x06, 165 | 0x00, 0x00, 0x00, 0x05, 166 | 0x00, 0x00, 0x00, 0x05, 167 | 0x00, 0x00, 0x00, 0x06, 168 | 0x00, 0x00, 0x00, 0x04, 169 | 0x00, 0x00, 0x00, 0x0F, 170 | 0x00, 0x00, 0x00, 0x5A, 171 | 0x00, 0x00, 0x00, 0x00, 172 | 0x00, 0x00, 0x00, 0x09, 173 | 0x0B, 0x0C, 0x0B, 0x0B, 174 | 0x03, 0x03, 0x11, 0x05, 175 | 0x01, 0x01, 0x01, 0x01, 176 | 0x00, 0x00, 0x00, 0x00, 177 | 0x00, 0x0D, 0x00, 0x00, 178 | 0xAE, 0x00, 0x01, 0x04, 179 | 0x00, 0x00, 0x00, 0x04, 180 | 0x00, 0x00, 0x00, 0x08, 181 | 0x00, 0x00, 0x00, 0x0A, 182 | 0x00, 0x00, 0x00, 0x0C, 183 | 0x00, 0x00, 0x00, 0x0D, 184 | 0x00, 0x00, 0x00, 0x0E, 185 | 0x00, 0x00, 0x00, 0x08, 186 | 0x00, 0x00, 0x00, 0x08, 187 | 0x00, 0x00, 0x00, 0x10, 188 | 0x00, 0x00, 0x00, 0x10, 189 | 0x00, 0x00, 0x00, 0x20, 190 | 0x00, 0x00, 0x00, 0x20, 191 | 0x00, 0x00, 0x00, 0x06, 192 | 0x00, 0x00, 0x05, 0x0A, 193 | 0x02, 0x00, 0x0C, 0x08, 194 | 0x00, 0x00, 0x00, 0x00, 195 | 0xAE, 0x40, 0x00, 0x40, 196 | 0x00, 0x00, 0x00, 0xFF, 197 | 0xAE, 0x44, 0x00, 0x40, 198 | 0x00, 0x10, 0x04, 0x01, 199 | 0xAE, 0x48, 0x00, 0x40, 200 | 0x00, 0x00, 0x10, 0x00, 201 | 0xAE, 0x4C, 0x00, 0x40, 202 | 0x00, 0x00, 0x00, 0x01, 203 | 0xAE, 0x50, 0x01, 0x40, 204 | 0x00, 0x00, 0x00, 0x14, 205 | 0x04, 0x00, 0x28, 0x00, 206 | 0x03, 0x20, 0x6C, 0x00, 207 | 0x00, 0x00, 0x00, 0x00, 208 | 0x00, 0x00, 0x00, 0x00, 209 | 0xAE, 0x64, 0x00, 0x40, 210 | 0x00, 0x00, 0x00, 0x01, 211 | 0xAE, 0xD8, 0x01, 0x00, 212 | 0x00, 0xC8, 0x05, 0xDC, 213 | 0x00, 0x00, 0x0C, 0xCD, 214 | 0x01, 0x04, 0x00, 0x00, 215 | 0x00, 0x01, 0x26, 0x01, 216 | 0xB5, 0x50, 0x02, 0x82, 217 | 0xA3, 0xE8, 0xA3, 0xB8, 218 | 0xA4, 0x38, 0xA4, 0x28, 219 | 0xA6, 0x48, 0xA4, 0x48, 220 | 0xA7, 0x88, 0xA7, 0x48, 221 | 0xAC, 0x10, 0xA7, 0x90, 222 | 0x99, 0xBC, 0x99, 0xB4, 223 | 0x9A, 0xFC, 0x9A, 0xBC, 224 | 0x00, 0x00, 0x00, 0x00, 225 | 0x00, 0x00, 0x00, 0x00, 226 | 0x00, 0x00, 0x00, 0x00, 227 | 0x00, 0x00, 0x00, 0x00, 228 | 0x00, 0x00, 0x00, 0x00, 229 | 0x00, 0x00, 0x00, 0x00, 230 | 0x00, 0x00, 0x00, 0x00, 231 | 0x00, 0x00, 0x00, 0x00, 232 | 0x00, 0x00, 0x00, 0x00, 233 | 0x00, 0x00, 0x00, 0x00, 234 | 0x00, 0x00, 0x00, 0x00, 235 | 0x00, 0x00, 0x00, 0x00, 236 | 0x00, 0x00, 0x00, 0x00, 237 | 0xB5, 0xA0, 0x02, 0x82, 238 | 0x00, 0x88, 0x03, 0x00, 239 | 0x00, 0x82, 0x00, 0x82, 240 | 0x04, 0x04, 0x04, 0x08, 241 | 0x00, 0x80, 0x04, 0x01, 242 | 0x09, 0x02, 0x09, 0x08, 243 | 0x04, 0x04, 0x00, 0x80, 244 | 0x04, 0x01, 0x04, 0x01, 245 | 0x00, 0x00, 0x00, 0x00, 246 | 0x00, 0x00, 0x00, 0x00, 247 | 0x00, 0x00, 0x00, 0x00, 248 | 0x00, 0x00, 0x00, 0x00, 249 | 0x00, 0x00, 0x00, 0x00, 250 | 0x00, 0x00, 0x00, 0x00, 251 | 0x00, 0x00, 0x00, 0x00, 252 | 0x00, 0x00, 0x00, 0x00, 253 | 0x00, 0x00, 0x00, 0x00, 254 | 0x00, 0x00, 0x00, 0x00, 255 | 0x00, 0x00, 0x00, 0x00, 256 | 0x00, 0x00, 0x00, 0x00, 257 | 0x00, 0x00, 0x00, 0x00, 258 | 0xB5, 0xF0, 0x00, 0x40, 259 | 0x00, 0x04, 0x00, 0x00, 260 | 0xB3, 0x9C, 0x01, 0x00, 261 | 0x40, 0x00, 0x05, 0x1E, 262 | 0x02, 0x1B, 0x08, 0x7C, 263 | 0x80, 0x01, 0x12, 0x01, 264 | 0x00, 0x00, 0x08, 0x00, 265 | 0xB6, 0xC0, 0x00, 0xC0, 266 | 0x00, 0x00, 0x60, 0x00, 267 | 0x00, 0x00, 0x20, 0x00, 268 | 0x00, 0x00, 0x00, 0x00, 269 | 0xAE, 0xA8, 0x00, 0x40, 270 | 0x00, 0x00, 0x04, 0x05, 271 | 0xAE, 0xAC, 0x00, 0x80, 272 | 0x01, 0x00, 0x01, 0x00, 273 | 0x00, 0x02, 0x00, 0x00, 274 | 0xAE, 0xB4, 0x00, 0x40, 275 | 0x00, 0x00, 0x00, 0x00, 276 | 0xAE, 0xB8, 0x00, 0x81, 277 | 0x00, 0x00, 0x00, 0x00, 278 | 0x00, 0x00, 0x00, 0x00, 279 | 0xAE, 0xC0, 0x00, 0x81, 280 | 0x00, 0x00, 0x00, 0x00, 281 | 0x00, 0x00, 0x00, 0x00, 282 | 0xAE, 0xC8, 0x00, 0x81, 283 | 0x08, 0x01, 0x01, 0x08, 284 | 0x00, 0x00, 0x00, 0x08, 285 | 0xAE, 0xD0, 0x00, 0x81, 286 | 0x01, 0x08, 0x08, 0x08, 287 | 0x00, 0x00, 0x00, 0x01, 288 | 0xB5, 0xF4, 0x00, 0x80, 289 | 0x00, 0x00, 0x00, 0x00, 290 | 0x00, 0x00, 0x00, 0x00, 291 | 0xB5, 0xFC, 0x00, 0x80, 292 | 0x00, 0x00, 0x00, 0x00, 293 | 0x00, 0x00, 0x00, 0x00, 294 | 0xB6, 0x04, 0x00, 0x40, 295 | 0x00, 0x00, 0x00, 0x00, 296 | 0xB6, 0x08, 0x00, 0x44, 297 | 0x00, 0x00, 0x00, 0x00, 298 | 0x00, 0x00, 0x00, 0x00, 299 | 0x00, 0x00, 0x00, 0x00, 300 | 0x00, 0x00, 0x00, 0x00, 301 | 0xB6, 0x18, 0x00, 0x44, 302 | 0x00, 0x00, 0x00, 0x00, 303 | 0x00, 0x00, 0x00, 0x00, 304 | 0x00, 0x00, 0x00, 0x00, 305 | 0x00, 0x00, 0x00, 0x00, 306 | 0xB6, 0x28, 0x00, 0x44, 307 | 0x00, 0x00, 0x00, 0x00, 308 | 0x00, 0x00, 0x00, 0x00, 309 | 0x00, 0x00, 0x00, 0x00, 310 | 0x00, 0x00, 0x00, 0x00, 311 | 0xB6, 0x38, 0x00, 0x44, 312 | 0x00, 0x00, 0x00, 0x00, 313 | 0x00, 0x00, 0x00, 0x00, 314 | 0x00, 0x00, 0x00, 0x00, 315 | 0x00, 0x00, 0x00, 0x00, 316 | 0xB6, 0x48, 0x01, 0x00, 317 | 0x00, 0x00, 0x00, 0x00, 318 | 0x00, 0x00, 0x00, 0x00, 319 | 0x00, 0x00, 0x00, 0x00, 320 | 0x00, 0x00, 0x00, 0x00, 321 | 0xB6, 0x58, 0x01, 0x00, 322 | 0x00, 0x00, 0x00, 0x00, 323 | 0x00, 0x00, 0x00, 0x00, 324 | 0x00, 0x00, 0x00, 0x00, 325 | 0x00, 0x00, 0x00, 0x00, 326 | 0xB6, 0x68, 0x01, 0x00, 327 | 0x00, 0x00, 0x00, 0x00, 328 | 0x00, 0x00, 0x00, 0x00, 329 | 0x00, 0x00, 0x00, 0x00, 330 | 0x00, 0x00, 0x00, 0x00, 331 | 0x54, 0x70, 0x00, 0x80, 332 | 0x00, 0x00, 0x00, 0x00, 333 | 0x00, 0x00, 0x00, 0x02, 334 | 0x00, 0x00, 0x00, 0x0F, 335 | 0x00, 0x01, 0x03, 0xD4 336 | }; 337 | 338 | #endif /* VL53L7CX_PLUGIN_XTALK_H_ */ 339 | --------------------------------------------------------------------------------