Skip to content

Commit 5a98b45

Browse files
committed
[driver] vl53 ext files temporary commit, to be submodule
1 parent 808ef24 commit 5a98b45

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

48 files changed

+56416
-0
lines changed

ext/vl53/vl53/.gitignore

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,2 @@
1+
*.zip
2+
__pycache__

ext/vl53/vl53/README.md

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,8 @@
1+
## ST ULD Drivers for VL53 Devices
2+
3+
This folder includes the ULD drivers for ST's VL53L5, VL53L7 and VL53L8 devices
4+
5+
The files are copied and modified to prefix global functions with "VL53_" and fixing typos to unify the APIs for the drivers.
6+
7+
To update the drivers, downlowd `STSW-IMG023.zip` and `STSW-IMG043_ULD.zip` from STs product page for VL53L5 and VL53L7/Vl53L8 devices.
8+
Then call `python update.py` to automatically unpack.

ext/vl53/vl53/update.py

Lines changed: 208 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,208 @@
1+
#!/usr/bin/env python3
2+
# generated by ChatGPT
3+
import os
4+
import shutil
5+
import zipfile
6+
import re
7+
8+
def extract_zip(zip_path, extract_to="."):
9+
print(f"Extracting {zip_path}...")
10+
with zipfile.ZipFile(zip_path, "r") as zip_ref:
11+
zip_ref.extractall(extract_to)
12+
13+
def find_subfolder(base_dir, pattern):
14+
"""Finds the first folder under base_dir containing the given pattern."""
15+
for root, dirs, _ in os.walk(base_dir):
16+
for d in dirs:
17+
if pattern in d:
18+
return os.path.join(root, d)
19+
return None
20+
21+
def copy_contents(api_folder, examples_folder, dest_folder):
22+
"""Copies API and Examples folders (skipping Platform)."""
23+
print(f"Copying contents to {dest_folder}...")
24+
25+
if os.path.exists(dest_folder):
26+
shutil.rmtree(dest_folder)
27+
os.makedirs(dest_folder)
28+
29+
# Copy top-level files (LICENSE if available)
30+
for fname in ["LICENSE.txt"]:
31+
src = os.path.join(api_folder, fname)
32+
if os.path.exists(src):
33+
shutil.copy(src, os.path.join(dest_folder, fname))
34+
35+
# Copy inc/, src/, examples/
36+
shutil.copytree(os.path.join(api_folder, "inc"), os.path.join(dest_folder, "inc"))
37+
shutil.copytree(os.path.join(api_folder, "src"), os.path.join(dest_folder, "src"))
38+
if os.path.exists(examples_folder):
39+
shutil.copytree(examples_folder, os.path.join(dest_folder, "examples"))
40+
41+
def perform_replacements(dest_folder, sensor_type):
42+
"""Perform all requested replacements in C and H files."""
43+
print(f"Performing replacements in {dest_folder} for {sensor_type}...")
44+
45+
replacements = {
46+
# both sensors: platform header rename
47+
r"\bplatform\.h\b": "vl53_platform.h",
48+
}
49+
50+
if sensor_type == "vl53l5cx":
51+
replacements.update({
52+
r"\bVL53L5CX_Platform\b": "VL53_Platform",
53+
r"\bVL53L5CX_RdByte\b": "VL53_RdByte",
54+
r"\bVL53L5CX_RdMulti\b": "VL53_RdMulti",
55+
r"\bVL53L5CX_WrByte\b": "VL53_WrByte",
56+
r"\bVL53L5CX_WrMulti\b": "VL53_WrMulti",
57+
r"\bVL53L5CX_Reset_Sensor\b": "VL53_Reset_Sensor",
58+
r"\bVL53L5CX_SwapBuffer\b": "VL53_SwapBuffer",
59+
r"\bVL53L5CX_WaitMs\b": "VL53_WaitMs",
60+
})
61+
elif sensor_type == "vl53lmz":
62+
replacements.update({
63+
r"\bVL53LMZ_Platform\b": "VL53_Platform",
64+
r"\bRdByte\b": "VL53_RdByte",
65+
r"\bRdMulti\b": "VL53_RdMulti",
66+
r"\bWrByte\b": "VL53_WrByte",
67+
r"\bWrMulti\b": "VL53_WrMulti",
68+
r"\bReset_Sensor\b": "VL53_Reset_Sensor",
69+
r"\bSwapBuffer\b": "VL53_SwapBuffer",
70+
r"\bWaitMs\b": "VL53_WaitMs",
71+
})
72+
73+
# Apply replacements recursively
74+
for root, _, files in os.walk(dest_folder):
75+
for fname in files:
76+
if fname.endswith((".c", ".h")):
77+
path = os.path.join(root, fname)
78+
with open(path, "r", encoding="utf-8") as f:
79+
lines = f.readlines()
80+
81+
new_lines = []
82+
for line in lines:
83+
# Skip any line containing "platform.address"
84+
if "platform.address" in line:
85+
continue
86+
new_lines.append(line)
87+
88+
content = "".join(new_lines)
89+
for pattern, repl in replacements.items():
90+
content = re.sub(pattern, repl, content)
91+
92+
with open(path, "w", encoding="utf-8") as f:
93+
f.write(content)
94+
95+
96+
def modify_examples(dest_folder, sensor_type):
97+
"""Rename .c to .h and update example function signatures and body."""
98+
examples_path = os.path.join(dest_folder, "examples")
99+
if not os.path.exists(examples_path):
100+
return
101+
102+
print(f"Updating example files in {examples_path}...")
103+
104+
for root, _, files in os.walk(examples_path):
105+
for fname in files:
106+
if not fname.endswith(".c"):
107+
continue
108+
109+
old_path = os.path.join(root, fname)
110+
new_path = os.path.splitext(old_path)[0] + ".h"
111+
os.rename(old_path, new_path)
112+
113+
with open(new_path, "r", encoding="utf-8") as f:
114+
lines = f.readlines()
115+
116+
new_lines = []
117+
inserted_transport = False
118+
for line in lines:
119+
# replace int example#(void) → int example#(void* transport)
120+
m = re.match(r"(\s*int\s+example\d+)\s*\(\s*void\s*\)", line)
121+
if m:
122+
line = re.sub(r"\(\s*void\s*\)", "(void* transport)", line)
123+
124+
if "printf" in line and "integration_time" in line:
125+
if not re.search(r"\(int\)\s*integration_time\w*\b", line):
126+
line = re.sub(r"\bintegration_time(\w*)\b", r"(int)integration_time\1", line)
127+
128+
new_lines.append(line)
129+
130+
# after Dev declaration, insert Dev.platform.transport = transport;
131+
if ("VL53LMZ_Configuration" in line or "VL53L5CX_Configuration" in line) and "Dev;" in line:
132+
new_lines.append(" Dev.platform.transport = transport;\n")
133+
inserted_transport = True
134+
135+
if not inserted_transport:
136+
print(f"⚠️ Warning: Did not insert transport assignment in {new_path}")
137+
138+
with open(new_path, "w", encoding="utf-8") as f:
139+
f.writelines(new_lines)
140+
141+
def cleanup(folder):
142+
"""Removes the extracted source folder and its empty parent."""
143+
if not os.path.exists(folder):
144+
return
145+
print(f"Cleaning up {folder}...")
146+
parent = os.path.dirname(folder)
147+
shutil.rmtree(folder, ignore_errors=True)
148+
try:
149+
if os.path.exists(parent) and not os.listdir(parent):
150+
print(f"Removing empty parent folder {parent}...")
151+
os.rmdir(parent)
152+
except Exception:
153+
pass
154+
155+
def process_package(zip_path, folder_hint, api_hint, examples_hint, dest_folder, sensor_type):
156+
"""Processes one STMicro package end-to-end."""
157+
if not os.path.exists(zip_path):
158+
print(f"❌ Error: {zip_path} not found.")
159+
return
160+
161+
extract_zip(zip_path)
162+
base_name = os.path.splitext(zip_path)[0]
163+
164+
# Try both extraction patterns
165+
root_folder = find_subfolder(".", folder_hint)
166+
if root_folder is None:
167+
root_folder = find_subfolder(base_name, folder_hint)
168+
if root_folder is None:
169+
raise FileNotFoundError(f"Could not find '{folder_hint}' folder in extracted contents of {zip_path}")
170+
171+
api_folder = find_subfolder(root_folder, api_hint)
172+
examples_folder = find_subfolder(root_folder, examples_hint)
173+
174+
if not all([api_folder, examples_folder]):
175+
raise FileNotFoundError(f"Missing expected subfolders in {root_folder}")
176+
177+
copy_contents(api_folder, examples_folder, dest_folder)
178+
perform_replacements(dest_folder, sensor_type)
179+
modify_examples(dest_folder, sensor_type)
180+
cleanup(root_folder)
181+
182+
print(f"✅ Finished processing {zip_path}{dest_folder}/\n")
183+
184+
def main():
185+
# Process VL53LMZ (STSW-IMG043_ULD.zip)
186+
process_package(
187+
zip_path="STSW-IMG043_ULD.zip",
188+
folder_hint="VL53LMZ_ULD_",
189+
api_hint="VL53LMZ_ULD_API",
190+
examples_hint="Examples",
191+
dest_folder="vl53lmz",
192+
sensor_type="vl53lmz"
193+
)
194+
195+
# Process VL53L5CX (STSW-IMG023.zip)
196+
process_package(
197+
zip_path="STSW-IMG023.zip",
198+
folder_hint="VL53L5CX_ULD_driver",
199+
api_hint="VL53L5CX_ULD_API",
200+
examples_hint="Examples",
201+
dest_folder="vl53l5cx",
202+
sensor_type="vl53l5cx"
203+
)
204+
205+
print("🎉 All updates completed successfully.")
206+
207+
if __name__ == "__main__":
208+
main()

ext/vl53/vl53/vl53l5cx/LICENSE.txt

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,6 @@
1+
This software component is provided to you as part of a software package and
2+
applicable license terms are in the Package_license file. If you received this
3+
software component outside of a package or without applicable license terms,
4+
the terms of the BSD-3-Clause license shall apply.
5+
You may obtain a copy of the BSD-3-Clause at:
6+
https://opensource.org/licenses/BSD-3-Clause
Lines changed: 152 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,152 @@
1+
/*******************************************************************************
2+
* Copyright (c) 2020, STMicroelectronics - All Rights Reserved
3+
*
4+
* This file, part of the VL53L8CX Ultra Lite Driver,
5+
* is licensed under terms that can be found in the LICENSE file
6+
* in the root directory of this software component.
7+
* If no LICENSE file comes with this software, it is provided AS-IS.
8+
*
9+
*******************************************************************************/
10+
11+
/***********************************/
12+
/* VL53L5CX ULD motion indicator */
13+
/***********************************/
14+
/*
15+
* This example shows the VL53L5CX motion indicator capabilities.
16+
* To use this example, user needs to be sure that macro
17+
* VL53L5CX_DISABLE_MOTION_INDICATOR is NOT enabled (see file vl53_platform.h).
18+
*/
19+
20+
#include <stdlib.h>
21+
#include <string.h>
22+
#include <stdio.h>
23+
#include "vl53l5cx_api.h"
24+
#include "vl53l5cx_plugin_motion_indicator.h"
25+
26+
int example10(void* transport)
27+
{
28+
29+
/*********************************/
30+
/* VL53L5CX ranging variables */
31+
/*********************************/
32+
33+
uint8_t status, loop, isAlive, isReady, i;
34+
VL53L5CX_Configuration Dev; /* Sensor configuration */
35+
Dev.platform.transport = transport;
36+
VL53L5CX_Motion_Configuration motion_config; /* Motion configuration*/
37+
VL53L5CX_ResultsData Results; /* Results data from VL53L5CX */
38+
39+
40+
/*********************************/
41+
/* Customer platform */
42+
/*********************************/
43+
44+
/* Fill the platform structure with customer's implementation. For this
45+
* example, only the I2C address is used.
46+
*/
47+
48+
/* (Optional) Reset sensor toggling PINs (see platform, not in API) */
49+
//VL53_Reset_Sensor(&(Dev.platform));
50+
51+
/* (Optional) Set a new I2C address if the wanted address is different
52+
* from the default one (filled with 0x20 for this example).
53+
*/
54+
//status = vl53l5cx_set_i2c_address(&Dev, 0x20);
55+
56+
57+
/*********************************/
58+
/* Power on sensor and init */
59+
/*********************************/
60+
61+
/* (Optional) Check if there is a VL53L5CX sensor connected */
62+
status = vl53l5cx_is_alive(&Dev, &isAlive);
63+
if(!isAlive || status)
64+
{
65+
printf("VL53L5CX not detected at requested address\n");
66+
return status;
67+
}
68+
69+
/* (Mandatory) Init VL53L5CX sensor */
70+
status = vl53l5cx_init(&Dev);
71+
if(status)
72+
{
73+
printf("VL53L5CX ULD Loading failed\n");
74+
return status;
75+
}
76+
77+
printf("VL53L5CX ULD ready ! (Version : %s)\n",
78+
VL53L5CX_API_REVISION);
79+
80+
81+
/*********************************/
82+
/* Program motion indicator */
83+
/*********************************/
84+
85+
/* Create motion indicator with resolution 4x4 */
86+
status = vl53l5cx_motion_indicator_init(&Dev, &motion_config, VL53L5CX_RESOLUTION_4X4);
87+
if(status)
88+
{
89+
printf("Motion indicator init failed with status : %u\n", status);
90+
return status;
91+
}
92+
93+
/* (Optional) Change the min and max distance used to detect motions. The
94+
* difference between min and max must never be >1500mm, and minimum never be <400mm,
95+
* otherwise the function below returns error 127 */
96+
status = vl53l5cx_motion_indicator_set_distance_motion(&Dev, &motion_config, 1000, 2000);
97+
if(status)
98+
{
99+
printf("Motion indicator set distance motion failed with status : %u\n", status);
100+
return status;
101+
}
102+
103+
/* If user want to change the resolution, he also needs to update the motion indicator resolution */
104+
//status = vl53l5cx_set_resolution(&Dev, VL53L5CX_RESOLUTION_4X4);
105+
//status = vl53l5cx_motion_indicator_set_resolution(&Dev, &motion_config, VL53L5CX_RESOLUTION_4X4);
106+
107+
/* Increase ranging frequency for the example */
108+
status = vl53l5cx_set_ranging_frequency_hz(&Dev, 2);
109+
110+
111+
/*********************************/
112+
/* Ranging loop */
113+
/*********************************/
114+
115+
status = vl53l5cx_start_ranging(&Dev);
116+
117+
loop = 0;
118+
while(loop < 10)
119+
{
120+
/* Use polling function to know when a new measurement is ready.
121+
* Another way can be to wait for HW interrupt raised on PIN A3
122+
* (GPIO 1) when a new measurement is ready */
123+
124+
status = vl53l5cx_check_data_ready(&Dev, &isReady);
125+
126+
if(isReady)
127+
{
128+
vl53l5cx_get_ranging_data(&Dev, &Results);
129+
130+
/* As the sensor is set in 4x4 mode by default, we have a total
131+
* of 16 zones to print. For this example, only the data of first zone are
132+
* print */
133+
printf("Print data no : %3u\n", Dev.streamcount);
134+
for(i = 0; i < 16; i++)
135+
{
136+
printf("Zone : %3d, Motion power : %3lu\n",
137+
i,
138+
Results.motion_indicator.motion[motion_config.map_id[i]]);
139+
}
140+
printf("\n");
141+
loop++;
142+
}
143+
144+
/* Wait a few ms to avoid too high polling (function in platform
145+
* file, not in API) */
146+
VL53_WaitMs(&(Dev.platform), 5);
147+
}
148+
149+
status = vl53l5cx_stop_ranging(&Dev);
150+
printf("End of ULD demo\n");
151+
return status;
152+
}

0 commit comments

Comments
 (0)