From 3fc62e61b9fee5da58f731723e6ccea9150534b2 Mon Sep 17 00:00:00 2001 From: Henrik Hose Date: Mon, 10 Nov 2025 21:13:16 +0100 Subject: [PATCH 1/6] [driver] vl53l5, vl53l7, vl53l8 driver and examples --- README.md | 2 + .../nucleo_h723zg/vl53/vl53l5cx_i2c/main.cpp | 60 +++++ .../vl53/vl53l5cx_i2c/project.xml | 15 ++ .../vl53/vl53l7_vl53l8_i2c/main.cpp | 59 +++++ .../vl53/vl53l7_vl53l8_i2c/project.xml | 15 ++ .../nucleo_h723zg/vl53/vl53l8_spi/main.cpp | 64 +++++ .../nucleo_h723zg/vl53/vl53l8_spi/project.xml | 15 ++ ext/vl53/vl53.hpp | 73 ++++++ ext/vl53/vl53.lb | 86 +++++++ ext/vl53/vl53_platform.h | 219 ++++++++++++++++++ ext/vl53/vl53_transport.hpp | 140 +++++++++++ ext/vl53/vl53_transport_impl.hpp | 182 +++++++++++++++ 12 files changed, 930 insertions(+) create mode 100644 examples/nucleo_h723zg/vl53/vl53l5cx_i2c/main.cpp create mode 100644 examples/nucleo_h723zg/vl53/vl53l5cx_i2c/project.xml create mode 100644 examples/nucleo_h723zg/vl53/vl53l7_vl53l8_i2c/main.cpp create mode 100644 examples/nucleo_h723zg/vl53/vl53l7_vl53l8_i2c/project.xml create mode 100644 examples/nucleo_h723zg/vl53/vl53l8_spi/main.cpp create mode 100644 examples/nucleo_h723zg/vl53/vl53l8_spi/project.xml create mode 100644 ext/vl53/vl53.hpp create mode 100644 ext/vl53/vl53.lb create mode 100644 ext/vl53/vl53_platform.h create mode 100644 ext/vl53/vl53_transport.hpp create mode 100644 ext/vl53/vl53_transport_impl.hpp diff --git a/README.md b/README.md index 7855ed70a1..a453aa8589 100644 --- a/README.md +++ b/README.md @@ -872,6 +872,8 @@ your specific needs. TOUCH2046 VL53L0 +VL53L5CX +VL53L7/VL53L8 VL6180 WS2812 diff --git a/examples/nucleo_h723zg/vl53/vl53l5cx_i2c/main.cpp b/examples/nucleo_h723zg/vl53/vl53l5cx_i2c/main.cpp new file mode 100644 index 0000000000..37dcbf503f --- /dev/null +++ b/examples/nucleo_h723zg/vl53/vl53l5cx_i2c/main.cpp @@ -0,0 +1,60 @@ +/* + * Copyright (c) 2025, Henrik Hose + * + * This file is part of the modm project. + * + * This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. + */ +// ---------------------------------------------------------------------------- + +#include +#include +#include + +// Tested with VL53L5CX-SATEL +extern "C" { +#include +#include +#include +#include +} + +using namespace Board; + +using I2c = I2cMaster1; +using Scl = GpioB8; // D15 +using Sda = GpioB9; // D14 + +using Int = GpioB5; +using Rst = GpioD14; +using PwrEn = GpioD15; +using LPn = GpioF3; + +modm::Vl53I2cTransport transport{VL53L5CX_DEFAULT_I2C_ADDRESS >> 1}; + +int +main() +{ + Board::initialize(); + + Leds::setOutput(); + + PwrEn::setOutput(true); + + LPn::setOutput(false); + // Snc::setOutput(false); + + transport.resetSensor(); + + I2c::connect(I2c::PullUps::External); + I2c::initialize(); + + uint8_t device_id, revision_id; + + example1(&transport); + example2(&transport); + example3(&transport); + example5(&transport); +} \ No newline at end of file diff --git a/examples/nucleo_h723zg/vl53/vl53l5cx_i2c/project.xml b/examples/nucleo_h723zg/vl53/vl53l5cx_i2c/project.xml new file mode 100644 index 0000000000..a1b77c30b2 --- /dev/null +++ b/examples/nucleo_h723zg/vl53/vl53l5cx_i2c/project.xml @@ -0,0 +1,15 @@ + + modm:nucleo-h723zg + + + + + + + modm:build:scons + modm:platform:dma + modm:platform:exti + modm:platform:i2c:1 + modm:vl53:vl53l5cx + + diff --git a/examples/nucleo_h723zg/vl53/vl53l7_vl53l8_i2c/main.cpp b/examples/nucleo_h723zg/vl53/vl53l7_vl53l8_i2c/main.cpp new file mode 100644 index 0000000000..69af665abb --- /dev/null +++ b/examples/nucleo_h723zg/vl53/vl53l7_vl53l8_i2c/main.cpp @@ -0,0 +1,59 @@ +/* + * Copyright (c) 2025, Henrik Hose + * + * This file is part of the modm project. + * + * This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. + */ +// ---------------------------------------------------------------------------- + +#include +#include +#include + +// Tested with MIKROE LIGHTRANGER 12 CLICK Breakout +// with VL53L8CH variant, so histogram example 12 is supported +extern "C" { +#include +#include +#include +#include +#include +} + +using namespace Board; + +using I2c = I2cMaster1; +using Scl = GpioB8; // D15 +using Sda = GpioB9; // D14 + +using Rst = GpioD6; +using Snc = GpioB1; +using LPn = GpioA3; +using Int = GpioD7; + +modm::Vl53I2cTransport transport{VL53LMZ_DEFAULT_I2C_ADDRESS >> 1}; + +int +main() +{ + Board::initialize(); + + Leds::setOutput(); + + LPn::setOutput(false); + Snc::setOutput(false); + + transport.resetSensor(); + + I2c::connect(I2c::PullUps::Internal); + I2c::initialize(); + + example1(&transport); + example2(&transport); + example3(&transport); + example5(&transport); + example12(&transport); +} \ No newline at end of file diff --git a/examples/nucleo_h723zg/vl53/vl53l7_vl53l8_i2c/project.xml b/examples/nucleo_h723zg/vl53/vl53l7_vl53l8_i2c/project.xml new file mode 100644 index 0000000000..9a1b137f44 --- /dev/null +++ b/examples/nucleo_h723zg/vl53/vl53l7_vl53l8_i2c/project.xml @@ -0,0 +1,15 @@ + + modm:nucleo-h723zg + + + + + + + modm:build:scons + modm:platform:dma + modm:platform:exti + modm:platform:i2c:1 + modm:vl53:vl53lmz + + diff --git a/examples/nucleo_h723zg/vl53/vl53l8_spi/main.cpp b/examples/nucleo_h723zg/vl53/vl53l8_spi/main.cpp new file mode 100644 index 0000000000..f5e378ce50 --- /dev/null +++ b/examples/nucleo_h723zg/vl53/vl53l8_spi/main.cpp @@ -0,0 +1,64 @@ +/* + * Copyright (c) 2025, Henrik Hose + * + * This file is part of the modm project. + * + * This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. + */ +// ---------------------------------------------------------------------------- + +#include + +// Tested with MIKROE LIGHTRANGER 12 CLICK Breakout +// with VL53L8CH variant, so histogram example 12 is supported +extern "C" { +#include +#include +#include +#include +#include +} + +#include +#include + +using namespace Board; + +using SpiMaster = SpiMaster2_Dma; +using Cs = GpioC0; +using Mosi = GpioB15; +using Miso = GpioC2; +using Sck = GpioD3; + +using Rst = GpioD6; +using Snc = GpioB1; +using LPn = GpioA3; +using Int = GpioD7; + +modm::Vl53SpiTransport transport; + +int +main() +{ + Board::initialize(); + + Dma1::enable(); + Leds::setOutput(); + + LPn::setOutput(false); + Snc::setOutput(false); + Cs::setOutput(true); + + transport.resetSensor(); + + SpiMaster::connect(); + SpiMaster::initialize(); + + example1(&transport); + example2(&transport); + example3(&transport); + example5(&transport); + example12(&transport); +} \ No newline at end of file diff --git a/examples/nucleo_h723zg/vl53/vl53l8_spi/project.xml b/examples/nucleo_h723zg/vl53/vl53l8_spi/project.xml new file mode 100644 index 0000000000..2f9a0b53ea --- /dev/null +++ b/examples/nucleo_h723zg/vl53/vl53l8_spi/project.xml @@ -0,0 +1,15 @@ + + modm:nucleo-h723zg + + + + + + + modm:build:scons + modm:platform:dma + modm:platform:exti + modm:platform:spi:2 + modm:vl53:vl53lmz + + diff --git a/ext/vl53/vl53.hpp b/ext/vl53/vl53.hpp new file mode 100644 index 0000000000..6c8b54c329 --- /dev/null +++ b/ext/vl53/vl53.hpp @@ -0,0 +1,73 @@ +/* + * Copyright (c) 2025, Henrik Hose + * + * This file is part of the modm project. + * + * This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. + */ +// ---------------------------------------------------------------------------- + +#include + +#include "vl53_transport.hpp" + +extern "C" { +#include "vl53_platform.h" + +uint8_t +VL53_RdByte(VL53_Platform *p_platform, uint16_t RegisterAddress, uint8_t *p_value) +{ + auto *iface = static_cast(p_platform->transport); + return iface->readByte(RegisterAddress, p_value); +} + +uint8_t +VL53_WrByte(VL53_Platform *p_platform, uint16_t RegisterAddress, uint8_t value) +{ + auto *iface = static_cast(p_platform->transport); + return iface->writeByte(RegisterAddress, value); +} + +uint8_t +VL53_WrMulti(VL53_Platform *p_platform, uint16_t RegisterAddress, uint8_t *p_values, uint32_t size) +{ + auto *iface = static_cast(p_platform->transport); + return iface->writeMulti(RegisterAddress, p_values, size); +} + +uint8_t +VL53_RdMulti(VL53_Platform *p_platform, uint16_t RegisterAddress, uint8_t *p_values, uint32_t size) +{ + auto *iface = static_cast(p_platform->transport); + return iface->readMulti(RegisterAddress, p_values, size); +} + +void +VL53_SwapBuffer(uint8_t *buffer, uint16_t size) +{ + uint32_t i, tmp; + + for (i = 0; i < size; i = i + 4) + { + tmp = (buffer[i] << 24) | (buffer[i + 1] << 16) | (buffer[i + 2] << 8) | (buffer[i + 3]); + + memcpy(&(buffer[i]), &tmp, 4); + } +} + +uint8_t +VL53_WaitMs(VL53_Platform *p_platform, uint32_t TimeMs) +{ + modm::delay_ms(TimeMs); + return 0; +} + +uint8_t +VL53_Reset_Sensor(VL53_Platform *p_platform) +{ + auto *iface = static_cast(p_platform->transport); + return iface->resetSensor(); +} +} \ No newline at end of file diff --git a/ext/vl53/vl53.lb b/ext/vl53/vl53.lb new file mode 100644 index 0000000000..371314d3bf --- /dev/null +++ b/ext/vl53/vl53.lb @@ -0,0 +1,86 @@ +#!/usr/bin/env python3 +# -*- coding: utf-8 -*- +# +# Copyright (c) 2025, Henrik Hose +# +# This file is part of the modm project. +# +# This Source Code Form is subject to the terms of the Mozilla Public +# License, v. 2.0. If a copy of the MPL was not distributed with this +# file, You can obtain one at http://mozilla.org/MPL/2.0/. +# ----------------------------------------------------------------------------- + +class Vl53l5cx(Module): + def init(self, module): + module.name = "vl53l5cx" + module.description = "Driver for ST VL53L5CX Multi-Zone Time-of-Flight Sensor" + + def prepare(self, module, options): + module.add_option( + BooleanOption( + name="examples", + description="", + default=False + ) + ) + return True + + def build(self, env): + env.outbasepath = "modm/ext" + env.copy("vl53/vl53l5cx/src") + env.copy("vl53/vl53l5cx/inc") + env.copy("vl53/vl53l5cx/LICENSE.txt") + if env[":vl53:vl53l5cx:examples"]: + env.copy("vl53/vl53l5cx/examples") + env.collect(":build:path.include", "modm/ext/vl53/") + env.collect(":build:path.include", "modm/ext/vl53/vl53l5cx/inc") + +class Vl53lmz(Module): + def init(self, module): + module.name = "vl53lmz" + module.description = "Driver for ST VL53L7 and VL53L8 Multi-Zone Time-of-Flight Sensors" + + def prepare(self, module, options): + module.add_option( + BooleanOption( + name="examples", + description="", + default=False + ) + ) + return True + + def build(self, env): + env.outbasepath = "modm/ext" + env.copy("vl53/vl53lmz/src") + env.copy("vl53/vl53lmz/inc") + env.copy("vl53/vl53lmz/LICENSE.txt") + if env[":vl53:vl53lmz:examples"]: + env.copy("vl53/vl53lmz/examples") + env.collect(":build:path.include", "modm/ext/vl53/") + env.collect(":build:path.include", "modm/ext/vl53/vl53lmz/inc") + +def init(module): + module.name = ":vl53" + module.description = """\ +# ST's VL53 Time-of-Flight ULD Drivers + +Currently supported sensors: + - With VL53LMZ driver: VL53L7CX, VL53L7CH, VL53L8CX, VL53L8CH + - VL53L5CX driver + +""" + +def prepare(module, options): + module.add_submodule(Vl53l5cx()) + module.add_submodule(Vl53lmz()) + module.depends(":architecture:spi.device") + module.depends(":architecture:i2c.device") + return True + +def build(env): + env.outbasepath = "modm/ext/vl53" + env.copy("vl53.hpp") + env.copy("vl53_transport.hpp") + env.copy("vl53_transport_impl.hpp") + env.copy("vl53_platform.h") \ No newline at end of file diff --git a/ext/vl53/vl53_platform.h b/ext/vl53/vl53_platform.h new file mode 100644 index 0000000000..e1d63c65c6 --- /dev/null +++ b/ext/vl53/vl53_platform.h @@ -0,0 +1,219 @@ +/** + * + * Copyright (c) 2021 STMicroelectronics. + * All rights reserved. + * + * + * This software component is provided to you as part of a software package and + * applicable license terms are in the Package_license file. If you received this + * software component outside of a package or without applicable license terms, + * the terms of the BSD-3-Clause license shall apply. + * You may obtain a copy of the BSD-3-Clause at: + * https://opensource.org/licenses/BSD-3-Clause + * + ****************************************************************************** + */ + +#ifndef VL53_PLATFORM_H_ +#define VL53_PLATFORM_H_ +#pragma once + +#include +#include + +/* + * @brief The macro below is used to define the number of target per zone sent + * through I2C. This value can be changed by user, in order to tune I2C + * transaction, and also the total memory size (a lower number of target per + * zone means a lower RAM). The value must be between 1 and 4. + */ + +#define VL53L5CX_NB_TARGET_PER_ZONE 1U + +/* + * @brief The macro below can be used to avoid data conversion into the driver. + * By default there is a conversion between firmware and user data. Using this macro + * allows to use the firmware format instead of user format. The firmware format allows + * an increased precision. + */ + +// #define VL53L5CX_USE_RAW_FORMAT + +/* + * @brief All macro below are used to configure the sensor output. User can + * define some macros if he wants to disable selected output, in order to reduce + * I2C access. + */ + +// #define VL53L5CX_DISABLE_AMBIENT_PER_SPAD +// #define VL53L5CX_DISABLE_NB_SPADS_ENABLED +// #define VL53L5CX_DISABLE_NB_TARGET_DETECTED +// #define VL53L5CX_DISABLE_SIGNAL_PER_SPAD +// #define VL53L5CX_DISABLE_RANGE_SIGMA_MM +// #define VL53L5CX_DISABLE_DISTANCE_MM +// #define VL53L5CX_DISABLE_REFLECTANCE_PERCENT +// #define VL53L5CX_DISABLE_TARGET_STATUS +// #define VL53L5CX_DISABLE_MOTION_INDICATOR + +/* + * @brief The macro below is used to define the number of target per zone sent + * through I2C. This value can be changed by user, in order to tune I2C + * transaction, and also the total memory size (a lower number of target per + * zone means a lower RAM usage). + */ + +#define VL53LMZ_NB_TARGET_PER_ZONE 1 + +/* + * @brief All macro below are used to configure the sensor output. User can + * define some macros if he wants to disable selected output, in order to reduce + * I2C access. + */ + +// #define VL53LMZ_DISABLE_AMBIENT_PER_SPAD +// #define VL53LMZ_DISABLE_NB_SPADS_ENABLED +// #define VL53LMZ_DISABLE_NB_TARGET_DETECTED +// #define VL53LMZ_DISABLE_SIGNAL_PER_SPAD +// #define VL53LMZ_DISABLE_RANGE_SIGMA_MM +// #define VL53LMZ_DISABLE_DISTANCE_MM +// #define VL53LMZ_DISABLE_REFLECTANCE_PERCENT +// #define VL53LMZ_DISABLE_TARGET_STATUS +// #define VL53LMZ_DISABLE_SCI + +/** + * @brief Structure VL53_Platform needs to be filled by the customer, + * depending on his platform. At least, it contains the VL53 I2C address. + * Some additional fields can be added, as descriptors, or platform + * dependencies. Anything added into this structure is visible into the platform + * layer. + */ + +typedef struct +{ + /* To be filled with customer's platform. At least an I2C address/descriptor + * needs to be added */ + /* Example for most standard platform : I2C address of sensor */ + uint16_t address; + + void *transport; + +} VL53_Platform; + +/* + * @brief The macro below is used to define the number of target per zone sent + * through I2C. This value can be changed by user, in order to tune I2C + * transaction, and also the total memory size (a lower number of target per + * zone means a lower RAM). The value must be between 1 and 4. + */ + +#define VL53_NB_TARGET_PER_ZONE 1U + +/* + * @brief The macro below can be used to avoid data conversion into the driver. + * By default there is a conversion between firmware and user data. Using this macro + * allows to use the firmware format instead of user format. The firmware format allows + * an increased precision. + */ + +// #define VL53_USE_RAW_FORMAT + +/* + * @brief All macro below are used to configure the sensor output. User can + * define some macros if he wants to disable selected output, in order to reduce + * I2C access. + */ + +// #define VL53_DISABLE_AMBIENT_PER_SPAD +// #define VL53_DISABLE_NB_SPADS_ENABLED +// #define VL53_DISABLE_NB_TARGET_DETECTED +// #define VL53_DISABLE_SIGNAL_PER_SPAD +// #define VL53_DISABLE_RANGE_SIGMA_MM +// #define VL53_DISABLE_DISTANCE_MM +// #define VL53_DISABLE_REFLECTANCE_PERCENT +// #define VL53_DISABLE_TARGET_STATUS +// #define VL53_DISABLE_MOTION_INDICATOR + +/** + * @param (VL53_Platform*) p_platform : Pointer of VL53 platform + * structure. + * @param (uint16_t) Address : I2C location of value to read. + * @param (uint8_t) *p_values : Pointer of value to read. + * @return (uint8_t) status : 0 if OK + */ + +uint8_t +VL53_RdByte(VL53_Platform *p_platform, uint16_t RegisterAdress, uint8_t *p_value); + +/** + * @brief Mandatory function used to write one single byte. + * @param (VL53_Platform*) p_platform : Pointer of VL53 platform + * structure. + * @param (uint16_t) Address : I2C location of value to read. + * @param (uint8_t) value : Pointer of value to write. + * @return (uint8_t) status : 0 if OK + */ + +uint8_t +VL53_WrByte(VL53_Platform *p_platform, uint16_t RegisterAdress, uint8_t value); + +/** + * @brief Mandatory function used to read multiples bytes. + * @param (VL53_Platform*) p_platform : Pointer of VL53 platform + * structure. + * @param (uint16_t) Address : I2C location of values to read. + * @param (uint8_t) *p_values : Buffer of bytes to read. + * @param (uint32_t) size : Size of *p_values buffer. + * @return (uint8_t) status : 0 if OK + */ + +uint8_t +VL53_RdMulti(VL53_Platform *p_platform, uint16_t RegisterAdress, uint8_t *p_values, uint32_t size); + +/** + * @brief Mandatory function used to write multiples bytes. + * @param (VL53_Platform*) p_platform : Pointer of VL53 platform + * structure. + * @param (uint16_t) Address : I2C location of values to write. + * @param (uint8_t) *p_values : Buffer of bytes to write. + * @param (uint32_t) size : Size of *p_values buffer. + * @return (uint8_t) status : 0 if OK + */ + +uint8_t +VL53_WrMulti(VL53_Platform *p_platform, uint16_t RegisterAdress, uint8_t *p_values, uint32_t size); + +/** + * @brief Optional function, only used to perform an hardware reset of the + * sensor. This function is not used in the API, but it can be used by the host. + * This function is not mandatory to fill if user don't want to reset the + * sensor. + * @param (VL53_Platform*) p_platform : Pointer of VL53 platform + * structure. + * @return (uint8_t) status : 0 if OK + */ + +uint8_t +VL53_Reset_Sensor(VL53_Platform *p_platform); + +/** + * @brief Mandatory function, used to swap a buffer. The buffer size is always a + * multiple of 4 (4, 8, 12, 16, ...). + * @param (uint8_t*) buffer : Buffer to swap, generally uint32_t + * @param (uint16_t) size : Buffer size to swap + */ + +void +VL53_SwapBuffer(uint8_t *buffer, uint16_t size); +/** + * @brief Mandatory function, used to wait during an amount of time. It must be + * filled as it's used into the API. + * @param (VL53_Platform*) p_platform : Pointer of VL53 platform + * structure. + * @param (uint32_t) TimeMs : Time to wait in ms. + * @return (uint8_t) status : 0 if wait is finished. + */ + +uint8_t +VL53_WaitMs(VL53_Platform *p_platform, uint32_t TimeMs); + +#endif // _PLATFORM_H_ \ No newline at end of file diff --git a/ext/vl53/vl53_transport.hpp b/ext/vl53/vl53_transport.hpp new file mode 100644 index 0000000000..c9ea4dfe57 --- /dev/null +++ b/ext/vl53/vl53_transport.hpp @@ -0,0 +1,140 @@ +/* + * Copyright (c) 2025, Henrik Hose + * + * This file is part of the modm project. + * + * This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. + */ +// ---------------------------------------------------------------------------- + +#ifndef MODM_VL53_TRANSPORT_HPP +#define MODM_VL53_TRANSPORT_HPP + +#include +#include +#include +#include +#include +#include +#include +#include + +namespace modm +{ + +class Vl53TransportBase +{ +public: + virtual ~Vl53TransportBase() = default; + + virtual uint8_t + writeMulti(uint16_t reg, const uint8_t *values, uint32_t size) = 0; + virtual uint8_t + readMulti(uint16_t reg, uint8_t *values, uint32_t size) = 0; + virtual uint8_t + writeByte(uint16_t reg, uint8_t value) = 0; + virtual uint8_t + readByte(uint16_t reg, uint8_t *value) = 0; + virtual uint8_t + resetSensor() = 0; +}; + +template +class Vl53SpiTransport : public modm::SpiDevice, public Vl53TransportBase +{ +public: + Vl53SpiTransport() + { + this->attachConfigurationHandler([] { + SpiMaster::setDataMode(SpiMaster::DataMode::Mode3); + SpiMaster::setDataOrder(SpiMaster::DataOrder::MsbFirst); + SpiMaster::setDataSize(SpiMaster::DataSize::Bit8); + }); + }; + + Vl53SpiTransport(const Vl53SpiTransport &) = delete; + + Vl53SpiTransport & + operator=(const Vl53SpiTransport &) = delete; + + uint8_t + writeMulti(uint16_t register_address, const uint8_t *p_values, uint32_t size) override; + + uint8_t + readMulti(uint16_t register_address, uint8_t *p_values, uint32_t size) override; + + uint8_t + readByte(uint16_t register_address, uint8_t *p_value) override + { + return this->readMulti(register_address, p_value, 1); + } + + uint8_t + writeByte(uint16_t register_address, uint8_t value) override + { + return this->writeMulti(register_address, &value, 1); + } + + uint8_t + resetSensor() override; + +private: + uint8_t tx_buffer[VL53LMZ_COMMS_CHUNK_SIZE + 2]; + uint8_t rx_buffer[VL53LMZ_COMMS_CHUNK_SIZE + 2]; + + static uint16_t + SPI_WRITE_MASK(uint16_t x) noexcept + { + return static_cast(x | 0x8000); + } + + static uint16_t + SPI_READ_MASK(uint16_t x) noexcept + { + return static_cast(x & static_cast(~0x8000)); + } +}; + +template +class Vl53I2cTransport : public modm::I2cDevice, public Vl53TransportBase +{ +public: + Vl53I2cTransport(const uint8_t address) : I2cDevice{address}, address_{address} {}; + + Vl53I2cTransport(const Vl53I2cTransport &) = delete; + + Vl53I2cTransport & + operator=(const Vl53I2cTransport &) = delete; + + inline void + SetAddress(const uint8_t address) + { + this->address_ = address; + }; + + uint8_t + writeMulti(uint16_t register_address, const uint8_t *p_values, uint32_t size) override; + + uint8_t + readMulti(uint16_t register_address, uint8_t *p_values, uint32_t size) override; + + inline uint8_t + readByte(uint16_t register_address, uint8_t *p_value) override; + + inline uint8_t + writeByte(uint16_t register_address, uint8_t value) override; + + uint8_t + resetSensor() override; + +private: + uint8_t address_; +}; + +} // namespace modm + +#include "vl53_transport_impl.hpp" + +#endif \ No newline at end of file diff --git a/ext/vl53/vl53_transport_impl.hpp b/ext/vl53/vl53_transport_impl.hpp new file mode 100644 index 0000000000..43bd5ed380 --- /dev/null +++ b/ext/vl53/vl53_transport_impl.hpp @@ -0,0 +1,182 @@ +/* + * Copyright (c) 2025, Henrik Hose + * + * This file is part of the modm project. + * + * This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. + */ +// ---------------------------------------------------------------------------- + +#ifndef MODM_VL53_TRANSPORT_HPP +#error "Don't include this file directly, use 'bmi088_transport.hpp' instead!" +#endif + +namespace modm +{ + +template +uint8_t +Vl53SpiTransport::writeMulti(uint16_t RegisterAddress, + const uint8_t *p_values, + uint32_t size) +{ + for (uint32_t position = 0; position < size; position += VL53LMZ_COMMS_CHUNK_SIZE) + { + uint32_t data_size = 0; + if (size > VL53LMZ_COMMS_CHUNK_SIZE) + { + if ((position + VL53LMZ_COMMS_CHUNK_SIZE) > size) + { + data_size = size - position; + } else + { + data_size = VL53LMZ_COMMS_CHUNK_SIZE; + } + } else + { + data_size = size; + } + + const uint16_t temp = RegisterAddress + position; + + tx_buffer[0] = SPI_WRITE_MASK(temp) >> 8; + tx_buffer[1] = SPI_WRITE_MASK(temp) & 0xFF; + + for (uint32_t i = 0; i < data_size; i++) { tx_buffer[i + 2] = p_values[position + i]; } + + data_size += 2; + + modm::this_fiber::poll([&] { return this->acquireMaster(); }); + Cs::reset(); + SpiMaster::transfer(&tx_buffer[0], nullptr, data_size); + + if (this->releaseMaster()) { Cs::set(); } + } + return 0; +} + +template +uint8_t +Vl53SpiTransport::readMulti(uint16_t RegisterAddress, + uint8_t *p_values, + uint32_t size) +{ + for (uint32_t position = 0; position < size; position += VL53LMZ_COMMS_CHUNK_SIZE) + { + uint32_t data_size = 0; + if (size > VL53LMZ_COMMS_CHUNK_SIZE) + { + if ((position + VL53LMZ_COMMS_CHUNK_SIZE) > size) + { + data_size = size - position; + } else + { + data_size = VL53LMZ_COMMS_CHUNK_SIZE; + } + } else + { + data_size = size; + } + + const uint16_t temp = RegisterAddress + position; + + tx_buffer[0] = SPI_READ_MASK(temp) >> 8; + tx_buffer[1] = SPI_READ_MASK(temp) & 0xFF; + + modm::this_fiber::poll([&] { return this->acquireMaster(); }); + Cs::reset(); + SpiMaster::transfer(&tx_buffer[0], &rx_buffer[0], data_size + 2); + // SpiMaster::transfer(nullptr, p_values + position, data_size); + if (this->releaseMaster()) { Cs::set(); } + + std::memcpy(p_values + position, &rx_buffer[2], data_size); + } + + return 0; +} + +template +uint8_t +Vl53SpiTransport::resetSensor() +{ + Lpn::reset(); + modm::this_fiber::sleep_for(100ms); + Lpn::set(); + modm::this_fiber::sleep_for(100ms); + return 0; +} + +template +uint8_t +Vl53I2cTransport::writeMulti(uint16_t RegisterAddress, const uint8_t *p_values, + uint32_t size) +{ + uint8_t data_write[size + 2]; + data_write[0] = (RegisterAddress >> 8) & 0xFF; + data_write[1] = RegisterAddress & 0xFF; + + std::memcpy(&data_write[2], p_values, size); + this->transaction.setAddress(address_); + const auto status = I2cDevice::write(&data_write[0], size + 2); + return static_cast(not status); +}; + +template +uint8_t +Vl53I2cTransport::readMulti(uint16_t RegisterAddress, uint8_t *p_values, + uint32_t size) +{ + uint8_t data_write[2]; + data_write[0] = (RegisterAddress >> 8) & 0xFF; + data_write[1] = RegisterAddress & 0xFF; + + this->transaction.setAddress(address_); + const auto status = I2cDevice::writeRead(&data_write[0], 2, p_values, size); + return static_cast(not status); +}; + +template +uint8_t +Vl53I2cTransport::readByte(uint16_t RegisterAddress, uint8_t *p_value) +{ + uint8_t data_write[2]; + uint8_t data_read[1]; + + data_write[0] = (RegisterAddress >> 8) & 0xFF; + data_write[1] = RegisterAddress & 0xFF; + + this->transaction.setAddress(address_); + const auto status = I2cDevice::writeRead(&data_write[0], 2, &data_read[0], 1); + *p_value = data_read[0]; + + return static_cast(not status); +} + +template +uint8_t +Vl53I2cTransport::writeByte(uint16_t RegisterAddress, uint8_t value) +{ + uint8_t data_write[3]; + + data_write[0] = (RegisterAddress >> 8) & 0xFF; + data_write[1] = RegisterAddress & 0xFF; + data_write[2] = value & 0xFF; + this->transaction.setAddress(address_); + const auto status = I2cDevice::write(&data_write[0], 3); + return static_cast(not status); +} + +template +uint8_t +Vl53I2cTransport::resetSensor() +{ + Lpn::reset(); + modm::this_fiber::sleep_for(100ms); + Lpn::set(); + modm::this_fiber::sleep_for(100ms); + return 0; +} + +} // namespace modm \ No newline at end of file From 4e716a4bd73f386b025bbf9e712046908d6f8387 Mon Sep 17 00:00:00 2001 From: Henrik Hose Date: Tue, 11 Nov 2025 23:23:48 +0100 Subject: [PATCH 2/6] [driver] Added vl53 ext submodule --- .gitmodules | 3 +++ README.md | 2 -- examples/nucleo_h723zg/vl53/vl53l5cx_i2c/main.cpp | 5 +++-- examples/nucleo_h723zg/vl53/vl53l7_vl53l8_i2c/main.cpp | 5 +++-- examples/nucleo_h723zg/vl53/vl53l8_spi/main.cpp | 4 ++-- ext/vl53/vl53 | 1 + ext/vl53/vl53.hpp | 2 +- ext/vl53/vl53.lb | 6 +++--- ext/vl53/vl53_platform.h | 4 ++++ 9 files changed, 20 insertions(+), 12 deletions(-) create mode 160000 ext/vl53/vl53 diff --git a/.gitmodules b/.gitmodules index eac70c4759..8a29d52395 100644 --- a/.gitmodules +++ b/.gitmodules @@ -52,3 +52,6 @@ [submodule "ext/segger/rtt"] path = ext/segger/rtt url = https://github.com/modm-ext/segger-rtt.git +[submodule "ext/vl53/vl53"] + path = ext/vl53/vl53 + url = https://github.com/modm-ext/vl53-partial.git \ No newline at end of file diff --git a/README.md b/README.md index a453aa8589..7855ed70a1 100644 --- a/README.md +++ b/README.md @@ -872,8 +872,6 @@ your specific needs. TOUCH2046 VL53L0 -VL53L5CX -VL53L7/VL53L8 VL6180 WS2812 diff --git a/examples/nucleo_h723zg/vl53/vl53l5cx_i2c/main.cpp b/examples/nucleo_h723zg/vl53/vl53l5cx_i2c/main.cpp index 37dcbf503f..6981a05e80 100644 --- a/examples/nucleo_h723zg/vl53/vl53l5cx_i2c/main.cpp +++ b/examples/nucleo_h723zg/vl53/vl53l5cx_i2c/main.cpp @@ -10,8 +10,6 @@ // ---------------------------------------------------------------------------- #include -#include -#include // Tested with VL53L5CX-SATEL extern "C" { @@ -21,6 +19,9 @@ extern "C" { #include } +#include +#include + using namespace Board; using I2c = I2cMaster1; diff --git a/examples/nucleo_h723zg/vl53/vl53l7_vl53l8_i2c/main.cpp b/examples/nucleo_h723zg/vl53/vl53l7_vl53l8_i2c/main.cpp index 69af665abb..f5702fd5e9 100644 --- a/examples/nucleo_h723zg/vl53/vl53l7_vl53l8_i2c/main.cpp +++ b/examples/nucleo_h723zg/vl53/vl53l7_vl53l8_i2c/main.cpp @@ -10,8 +10,6 @@ // ---------------------------------------------------------------------------- #include -#include -#include // Tested with MIKROE LIGHTRANGER 12 CLICK Breakout // with VL53L8CH variant, so histogram example 12 is supported @@ -23,6 +21,9 @@ extern "C" { #include } +#include +#include + using namespace Board; using I2c = I2cMaster1; diff --git a/examples/nucleo_h723zg/vl53/vl53l8_spi/main.cpp b/examples/nucleo_h723zg/vl53/vl53l8_spi/main.cpp index f5e378ce50..226a6e5772 100644 --- a/examples/nucleo_h723zg/vl53/vl53l8_spi/main.cpp +++ b/examples/nucleo_h723zg/vl53/vl53l8_spi/main.cpp @@ -21,8 +21,8 @@ extern "C" { #include } -#include -#include +#include +#include using namespace Board; diff --git a/ext/vl53/vl53 b/ext/vl53/vl53 new file mode 160000 index 0000000000..e41b8561a8 --- /dev/null +++ b/ext/vl53/vl53 @@ -0,0 +1 @@ +Subproject commit e41b8561a8168eaf2a7c68379cd21686b173c78c diff --git a/ext/vl53/vl53.hpp b/ext/vl53/vl53.hpp index 6c8b54c329..f7424c0f58 100644 --- a/ext/vl53/vl53.hpp +++ b/ext/vl53/vl53.hpp @@ -60,7 +60,7 @@ VL53_SwapBuffer(uint8_t *buffer, uint16_t size) uint8_t VL53_WaitMs(VL53_Platform *p_platform, uint32_t TimeMs) { - modm::delay_ms(TimeMs); + modm::this_fiber::sleep_for(std::chrono::milliseconds(TimeMs)); return 0; } diff --git a/ext/vl53/vl53.lb b/ext/vl53/vl53.lb index 371314d3bf..4d4ed65a22 100644 --- a/ext/vl53/vl53.lb +++ b/ext/vl53/vl53.lb @@ -32,7 +32,7 @@ class Vl53l5cx(Module): env.copy("vl53/vl53l5cx/LICENSE.txt") if env[":vl53:vl53l5cx:examples"]: env.copy("vl53/vl53l5cx/examples") - env.collect(":build:path.include", "modm/ext/vl53/") + env.collect(":build:path.include", "modm/src/modm/driver/vl53") env.collect(":build:path.include", "modm/ext/vl53/vl53l5cx/inc") class Vl53lmz(Module): @@ -57,7 +57,7 @@ class Vl53lmz(Module): env.copy("vl53/vl53lmz/LICENSE.txt") if env[":vl53:vl53lmz:examples"]: env.copy("vl53/vl53lmz/examples") - env.collect(":build:path.include", "modm/ext/vl53/") + env.collect(":build:path.include", "modm/src/modm/driver/vl53") env.collect(":build:path.include", "modm/ext/vl53/vl53lmz/inc") def init(module): @@ -79,7 +79,7 @@ def prepare(module, options): return True def build(env): - env.outbasepath = "modm/ext/vl53" + env.outbasepath = "modm/src/modm/driver/vl53" env.copy("vl53.hpp") env.copy("vl53_transport.hpp") env.copy("vl53_transport_impl.hpp") diff --git a/ext/vl53/vl53_platform.h b/ext/vl53/vl53_platform.h index e1d63c65c6..30383ec7b0 100644 --- a/ext/vl53/vl53_platform.h +++ b/ext/vl53/vl53_platform.h @@ -18,6 +18,10 @@ #define VL53_PLATFORM_H_ #pragma once +#if __has_include("modm_config_vl53.h") +#include "modm_config_vl53.h" +#endif + #include #include From a28ccd0e89051cddb552f3851e910d171f3cd262 Mon Sep 17 00:00:00 2001 From: Henrik Hose Date: Mon, 17 Nov 2025 10:13:32 +0100 Subject: [PATCH 3/6] [driver] vl53 remove examples from lbuild --- .../nucleo_h723zg/vl53/vl53l5cx_i2c/main.cpp | 8 ++++---- .../vl53/vl53l5cx_i2c/project.xml | 1 - .../vl53/vl53l7_vl53l8_i2c/main.cpp | 10 +++++----- .../vl53/vl53l7_vl53l8_i2c/project.xml | 1 - .../nucleo_h723zg/vl53/vl53l8_spi/main.cpp | 10 +++++----- .../nucleo_h723zg/vl53/vl53l8_spi/project.xml | 1 - ext/vl53/vl53.lb | 18 ------------------ 7 files changed, 14 insertions(+), 35 deletions(-) diff --git a/examples/nucleo_h723zg/vl53/vl53l5cx_i2c/main.cpp b/examples/nucleo_h723zg/vl53/vl53l5cx_i2c/main.cpp index 6981a05e80..caf0650760 100644 --- a/examples/nucleo_h723zg/vl53/vl53l5cx_i2c/main.cpp +++ b/examples/nucleo_h723zg/vl53/vl53l5cx_i2c/main.cpp @@ -13,10 +13,10 @@ // Tested with VL53L5CX-SATEL extern "C" { -#include -#include -#include -#include +#include "../../../../ext/vl53/vl53/vl53l5cx/examples/Example_1_ranging_basic.h" +#include "../../../../ext/vl53/vl53/vl53l5cx/examples/Example_2_get_set_params.h" +#include "../../../../ext/vl53/vl53/vl53l5cx/examples/Example_3_ranging_modes.h" +#include "../../../../ext/vl53/vl53/vl53l5cx/examples/Example_5_multiple_targets_per_zone.h" } #include diff --git a/examples/nucleo_h723zg/vl53/vl53l5cx_i2c/project.xml b/examples/nucleo_h723zg/vl53/vl53l5cx_i2c/project.xml index a1b77c30b2..710d70da98 100644 --- a/examples/nucleo_h723zg/vl53/vl53l5cx_i2c/project.xml +++ b/examples/nucleo_h723zg/vl53/vl53l5cx_i2c/project.xml @@ -2,7 +2,6 @@ modm:nucleo-h723zg - diff --git a/examples/nucleo_h723zg/vl53/vl53l7_vl53l8_i2c/main.cpp b/examples/nucleo_h723zg/vl53/vl53l7_vl53l8_i2c/main.cpp index f5702fd5e9..8452626124 100644 --- a/examples/nucleo_h723zg/vl53/vl53l7_vl53l8_i2c/main.cpp +++ b/examples/nucleo_h723zg/vl53/vl53l7_vl53l8_i2c/main.cpp @@ -14,11 +14,11 @@ // Tested with MIKROE LIGHTRANGER 12 CLICK Breakout // with VL53L8CH variant, so histogram example 12 is supported extern "C" { -#include -#include -#include -#include -#include +#include "../../../../ext/vl53/vl53/vl53lmz/examples/Example_12_cnh_data.h" +#include "../../../../ext/vl53/vl53/vl53lmz/examples/Example_1_ranging_basic.h" +#include "../../../../ext/vl53/vl53/vl53lmz/examples/Example_2_get_set_params.h" +#include "../../../../ext/vl53/vl53/vl53lmz/examples/Example_3_ranging_modes.h" +#include "../../../../ext/vl53/vl53/vl53lmz/examples/Example_5_multiple_targets_per_zone.h" } #include diff --git a/examples/nucleo_h723zg/vl53/vl53l7_vl53l8_i2c/project.xml b/examples/nucleo_h723zg/vl53/vl53l7_vl53l8_i2c/project.xml index 9a1b137f44..552e84e29b 100644 --- a/examples/nucleo_h723zg/vl53/vl53l7_vl53l8_i2c/project.xml +++ b/examples/nucleo_h723zg/vl53/vl53l7_vl53l8_i2c/project.xml @@ -2,7 +2,6 @@ modm:nucleo-h723zg - diff --git a/examples/nucleo_h723zg/vl53/vl53l8_spi/main.cpp b/examples/nucleo_h723zg/vl53/vl53l8_spi/main.cpp index 226a6e5772..7ce22e2361 100644 --- a/examples/nucleo_h723zg/vl53/vl53l8_spi/main.cpp +++ b/examples/nucleo_h723zg/vl53/vl53l8_spi/main.cpp @@ -14,11 +14,11 @@ // Tested with MIKROE LIGHTRANGER 12 CLICK Breakout // with VL53L8CH variant, so histogram example 12 is supported extern "C" { -#include -#include -#include -#include -#include +#include "../../../../ext/vl53/vl53/vl53lmz/examples/Example_12_cnh_data.h" +#include "../../../../ext/vl53/vl53/vl53lmz/examples/Example_1_ranging_basic.h" +#include "../../../../ext/vl53/vl53/vl53lmz/examples/Example_2_get_set_params.h" +#include "../../../../ext/vl53/vl53/vl53lmz/examples/Example_3_ranging_modes.h" +#include "../../../../ext/vl53/vl53/vl53lmz/examples/Example_5_multiple_targets_per_zone.h" } #include diff --git a/examples/nucleo_h723zg/vl53/vl53l8_spi/project.xml b/examples/nucleo_h723zg/vl53/vl53l8_spi/project.xml index 2f9a0b53ea..2652ad5ed1 100644 --- a/examples/nucleo_h723zg/vl53/vl53l8_spi/project.xml +++ b/examples/nucleo_h723zg/vl53/vl53l8_spi/project.xml @@ -2,7 +2,6 @@ modm:nucleo-h723zg - diff --git a/ext/vl53/vl53.lb b/ext/vl53/vl53.lb index 4d4ed65a22..f6ef508626 100644 --- a/ext/vl53/vl53.lb +++ b/ext/vl53/vl53.lb @@ -16,13 +16,6 @@ class Vl53l5cx(Module): module.description = "Driver for ST VL53L5CX Multi-Zone Time-of-Flight Sensor" def prepare(self, module, options): - module.add_option( - BooleanOption( - name="examples", - description="", - default=False - ) - ) return True def build(self, env): @@ -30,8 +23,6 @@ class Vl53l5cx(Module): env.copy("vl53/vl53l5cx/src") env.copy("vl53/vl53l5cx/inc") env.copy("vl53/vl53l5cx/LICENSE.txt") - if env[":vl53:vl53l5cx:examples"]: - env.copy("vl53/vl53l5cx/examples") env.collect(":build:path.include", "modm/src/modm/driver/vl53") env.collect(":build:path.include", "modm/ext/vl53/vl53l5cx/inc") @@ -41,13 +32,6 @@ class Vl53lmz(Module): module.description = "Driver for ST VL53L7 and VL53L8 Multi-Zone Time-of-Flight Sensors" def prepare(self, module, options): - module.add_option( - BooleanOption( - name="examples", - description="", - default=False - ) - ) return True def build(self, env): @@ -55,8 +39,6 @@ class Vl53lmz(Module): env.copy("vl53/vl53lmz/src") env.copy("vl53/vl53lmz/inc") env.copy("vl53/vl53lmz/LICENSE.txt") - if env[":vl53:vl53lmz:examples"]: - env.copy("vl53/vl53lmz/examples") env.collect(":build:path.include", "modm/src/modm/driver/vl53") env.collect(":build:path.include", "modm/ext/vl53/vl53lmz/inc") From ead07413614278a108914cbf5104f5f3eb0fcecb Mon Sep 17 00:00:00 2001 From: Henrik Hose Date: Wed, 19 Nov 2025 11:38:43 +0100 Subject: [PATCH 4/6] [driver] vl53 multiwrite with i2c eeprom --- .../vl53/vl53l7_vl53l8_i2c/project.xml | 2 +- ext/vl53/vl53.lb | 1 + ext/vl53/vl53_transport.hpp | 15 +++++++-------- ext/vl53/vl53_transport_impl.hpp | 12 ++---------- 4 files changed, 11 insertions(+), 19 deletions(-) diff --git a/examples/nucleo_h723zg/vl53/vl53l7_vl53l8_i2c/project.xml b/examples/nucleo_h723zg/vl53/vl53l7_vl53l8_i2c/project.xml index 552e84e29b..5a23ff321b 100644 --- a/examples/nucleo_h723zg/vl53/vl53l7_vl53l8_i2c/project.xml +++ b/examples/nucleo_h723zg/vl53/vl53l7_vl53l8_i2c/project.xml @@ -2,7 +2,7 @@ modm:nucleo-h723zg - + modm:build:scons diff --git a/ext/vl53/vl53.lb b/ext/vl53/vl53.lb index f6ef508626..f0ecba1e6b 100644 --- a/ext/vl53/vl53.lb +++ b/ext/vl53/vl53.lb @@ -58,6 +58,7 @@ def prepare(module, options): module.add_submodule(Vl53lmz()) module.depends(":architecture:spi.device") module.depends(":architecture:i2c.device") + module.depends(":driver:i2c.eeprom") return True def build(env): diff --git a/ext/vl53/vl53_transport.hpp b/ext/vl53/vl53_transport.hpp index c9ea4dfe57..46c444cf6a 100644 --- a/ext/vl53/vl53_transport.hpp +++ b/ext/vl53/vl53_transport.hpp @@ -16,6 +16,7 @@ #include #include #include +#include #include #include #include @@ -98,20 +99,21 @@ class Vl53SpiTransport : public modm::SpiDevice, public Vl53Transport }; template -class Vl53I2cTransport : public modm::I2cDevice, public Vl53TransportBase +class Vl53I2cTransport : public modm::I2cDevice, public Vl53TransportBase, private I2cEeprom { public: - Vl53I2cTransport(const uint8_t address) : I2cDevice{address}, address_{address} {}; + Vl53I2cTransport(const uint8_t address) : I2cDevice{address}, I2cEeprom{address} {}; Vl53I2cTransport(const Vl53I2cTransport &) = delete; Vl53I2cTransport & operator=(const Vl53I2cTransport &) = delete; - inline void - SetAddress(const uint8_t address) + void + setAddress(const uint8_t address) { - this->address_ = address; + I2cEeprom::transaction.setAddress(address); + I2cDevice::transaction.setAddress(address); }; uint8_t @@ -128,9 +130,6 @@ class Vl53I2cTransport : public modm::I2cDevice, public Vl53Transport uint8_t resetSensor() override; - -private: - uint8_t address_; }; } // namespace modm diff --git a/ext/vl53/vl53_transport_impl.hpp b/ext/vl53/vl53_transport_impl.hpp index 43bd5ed380..8c3074c38a 100644 --- a/ext/vl53/vl53_transport_impl.hpp +++ b/ext/vl53/vl53_transport_impl.hpp @@ -113,13 +113,7 @@ uint8_t Vl53I2cTransport::writeMulti(uint16_t RegisterAddress, const uint8_t *p_values, uint32_t size) { - uint8_t data_write[size + 2]; - data_write[0] = (RegisterAddress >> 8) & 0xFF; - data_write[1] = RegisterAddress & 0xFF; - - std::memcpy(&data_write[2], p_values, size); - this->transaction.setAddress(address_); - const auto status = I2cDevice::write(&data_write[0], size + 2); + const auto status = I2cEeprom::write(RegisterAddress, p_values, size); return static_cast(not status); }; @@ -132,7 +126,6 @@ Vl53I2cTransport::readMulti(uint16_t RegisterAddress, uint8_t *p data_write[0] = (RegisterAddress >> 8) & 0xFF; data_write[1] = RegisterAddress & 0xFF; - this->transaction.setAddress(address_); const auto status = I2cDevice::writeRead(&data_write[0], 2, p_values, size); return static_cast(not status); }; @@ -147,7 +140,6 @@ Vl53I2cTransport::readByte(uint16_t RegisterAddress, uint8_t *p_ data_write[0] = (RegisterAddress >> 8) & 0xFF; data_write[1] = RegisterAddress & 0xFF; - this->transaction.setAddress(address_); const auto status = I2cDevice::writeRead(&data_write[0], 2, &data_read[0], 1); *p_value = data_read[0]; @@ -163,7 +155,7 @@ Vl53I2cTransport::writeByte(uint16_t RegisterAddress, uint8_t va data_write[0] = (RegisterAddress >> 8) & 0xFF; data_write[1] = RegisterAddress & 0xFF; data_write[2] = value & 0xFF; - this->transaction.setAddress(address_); + const auto status = I2cDevice::write(&data_write[0], 3); return static_cast(not status); } From 752496dec54cd026a45c08de1197ea99588351b1 Mon Sep 17 00:00:00 2001 From: Henrik Hose Date: Wed, 19 Nov 2025 11:43:27 +0100 Subject: [PATCH 5/6] [driver] vl53 spi driver without tx buffer, fails with DMA --- .../nucleo_h723zg/vl53/vl53l8_spi/main.cpp | 3 ++- ext/vl53/vl53_transport.hpp | 1 - ext/vl53/vl53_transport_impl.hpp | 22 +++++++++---------- 3 files changed, 13 insertions(+), 13 deletions(-) diff --git a/examples/nucleo_h723zg/vl53/vl53l8_spi/main.cpp b/examples/nucleo_h723zg/vl53/vl53l8_spi/main.cpp index 7ce22e2361..8033436ae4 100644 --- a/examples/nucleo_h723zg/vl53/vl53l8_spi/main.cpp +++ b/examples/nucleo_h723zg/vl53/vl53l8_spi/main.cpp @@ -26,7 +26,8 @@ extern "C" { using namespace Board; -using SpiMaster = SpiMaster2_Dma; +// using SpiMaster = SpiMaster2_Dma; +using SpiMaster = SpiMaster2; using Cs = GpioC0; using Mosi = GpioB15; using Miso = GpioC2; diff --git a/ext/vl53/vl53_transport.hpp b/ext/vl53/vl53_transport.hpp index 46c444cf6a..a5a75c15c8 100644 --- a/ext/vl53/vl53_transport.hpp +++ b/ext/vl53/vl53_transport.hpp @@ -82,7 +82,6 @@ class Vl53SpiTransport : public modm::SpiDevice, public Vl53Transport resetSensor() override; private: - uint8_t tx_buffer[VL53LMZ_COMMS_CHUNK_SIZE + 2]; uint8_t rx_buffer[VL53LMZ_COMMS_CHUNK_SIZE + 2]; static uint16_t diff --git a/ext/vl53/vl53_transport_impl.hpp b/ext/vl53/vl53_transport_impl.hpp index 8c3074c38a..cc020bb90f 100644 --- a/ext/vl53/vl53_transport_impl.hpp +++ b/ext/vl53/vl53_transport_impl.hpp @@ -41,16 +41,15 @@ Vl53SpiTransport::writeMulti(uint1 const uint16_t temp = RegisterAddress + position; - tx_buffer[0] = SPI_WRITE_MASK(temp) >> 8; - tx_buffer[1] = SPI_WRITE_MASK(temp) & 0xFF; - - for (uint32_t i = 0; i < data_size; i++) { tx_buffer[i + 2] = p_values[position + i]; } - - data_size += 2; + uint8_t addr_buffer[2]; + addr_buffer[0] = SPI_WRITE_MASK(temp) >> 8; + addr_buffer[1] = SPI_WRITE_MASK(temp) & 0xFF; modm::this_fiber::poll([&] { return this->acquireMaster(); }); Cs::reset(); - SpiMaster::transfer(&tx_buffer[0], nullptr, data_size); + // SpiMaster::transfer(&tx_buffer[0], nullptr, data_size); + SpiMaster::transfer(addr_buffer, nullptr, sizeof(addr_buffer)); + SpiMaster::transfer(&p_values[position], nullptr, data_size); if (this->releaseMaster()) { Cs::set(); } } @@ -82,12 +81,13 @@ Vl53SpiTransport::readMulti(uint16 const uint16_t temp = RegisterAddress + position; - tx_buffer[0] = SPI_READ_MASK(temp) >> 8; - tx_buffer[1] = SPI_READ_MASK(temp) & 0xFF; + uint8_t addr_buffer[2]; + addr_buffer[0] = SPI_WRITE_MASK(temp) >> 8; + addr_buffer[1] = SPI_WRITE_MASK(temp) & 0xFF; modm::this_fiber::poll([&] { return this->acquireMaster(); }); Cs::reset(); - SpiMaster::transfer(&tx_buffer[0], &rx_buffer[0], data_size + 2); + SpiMaster::transfer(&addr_buffer[0], &rx_buffer[0], data_size + 2); // SpiMaster::transfer(nullptr, p_values + position, data_size); if (this->releaseMaster()) { Cs::set(); } @@ -155,7 +155,7 @@ Vl53I2cTransport::writeByte(uint16_t RegisterAddress, uint8_t va data_write[0] = (RegisterAddress >> 8) & 0xFF; data_write[1] = RegisterAddress & 0xFF; data_write[2] = value & 0xFF; - + const auto status = I2cDevice::write(&data_write[0], 3); return static_cast(not status); } From 055c6f22e9ea4aa7a3b9434c5c629e5309a4e874 Mon Sep 17 00:00:00 2001 From: Henrik Hose Date: Thu, 20 Nov 2025 13:15:13 +0100 Subject: [PATCH 6/6] [driver] vl53 fixup --- .../nucleo_h723zg/vl53/vl53l8_spi/main.cpp | 3 +-- ext/vl53/vl53_transport.hpp | 12 +++-------- ext/vl53/vl53_transport_impl.hpp | 20 +++++-------------- 3 files changed, 9 insertions(+), 26 deletions(-) diff --git a/examples/nucleo_h723zg/vl53/vl53l8_spi/main.cpp b/examples/nucleo_h723zg/vl53/vl53l8_spi/main.cpp index 8033436ae4..7ce22e2361 100644 --- a/examples/nucleo_h723zg/vl53/vl53l8_spi/main.cpp +++ b/examples/nucleo_h723zg/vl53/vl53l8_spi/main.cpp @@ -26,8 +26,7 @@ extern "C" { using namespace Board; -// using SpiMaster = SpiMaster2_Dma; -using SpiMaster = SpiMaster2; +using SpiMaster = SpiMaster2_Dma; using Cs = GpioC0; using Mosi = GpioB15; using Miso = GpioC2; diff --git a/ext/vl53/vl53_transport.hpp b/ext/vl53/vl53_transport.hpp index a5a75c15c8..76aa610c38 100644 --- a/ext/vl53/vl53_transport.hpp +++ b/ext/vl53/vl53_transport.hpp @@ -82,6 +82,7 @@ class Vl53SpiTransport : public modm::SpiDevice, public Vl53Transport resetSensor() override; private: + uint8_t addr_buffer[2]; uint8_t rx_buffer[VL53LMZ_COMMS_CHUNK_SIZE + 2]; static uint16_t @@ -98,23 +99,16 @@ class Vl53SpiTransport : public modm::SpiDevice, public Vl53Transport }; template -class Vl53I2cTransport : public modm::I2cDevice, public Vl53TransportBase, private I2cEeprom +class Vl53I2cTransport : public I2cEeprom, public Vl53TransportBase { public: - Vl53I2cTransport(const uint8_t address) : I2cDevice{address}, I2cEeprom{address} {}; + Vl53I2cTransport(const uint8_t address) : I2cEeprom{address} {}; Vl53I2cTransport(const Vl53I2cTransport &) = delete; Vl53I2cTransport & operator=(const Vl53I2cTransport &) = delete; - void - setAddress(const uint8_t address) - { - I2cEeprom::transaction.setAddress(address); - I2cDevice::transaction.setAddress(address); - }; - uint8_t writeMulti(uint16_t register_address, const uint8_t *p_values, uint32_t size) override; diff --git a/ext/vl53/vl53_transport_impl.hpp b/ext/vl53/vl53_transport_impl.hpp index cc020bb90f..3c893c41d3 100644 --- a/ext/vl53/vl53_transport_impl.hpp +++ b/ext/vl53/vl53_transport_impl.hpp @@ -41,7 +41,6 @@ Vl53SpiTransport::writeMulti(uint1 const uint16_t temp = RegisterAddress + position; - uint8_t addr_buffer[2]; addr_buffer[0] = SPI_WRITE_MASK(temp) >> 8; addr_buffer[1] = SPI_WRITE_MASK(temp) & 0xFF; @@ -82,13 +81,12 @@ Vl53SpiTransport::readMulti(uint16 const uint16_t temp = RegisterAddress + position; uint8_t addr_buffer[2]; - addr_buffer[0] = SPI_WRITE_MASK(temp) >> 8; - addr_buffer[1] = SPI_WRITE_MASK(temp) & 0xFF; + addr_buffer[0] = SPI_READ_MASK(temp) >> 8; + addr_buffer[1] = SPI_READ_MASK(temp) & 0xFF; modm::this_fiber::poll([&] { return this->acquireMaster(); }); Cs::reset(); SpiMaster::transfer(&addr_buffer[0], &rx_buffer[0], data_size + 2); - // SpiMaster::transfer(nullptr, p_values + position, data_size); if (this->releaseMaster()) { Cs::set(); } std::memcpy(p_values + position, &rx_buffer[2], data_size); @@ -126,7 +124,7 @@ Vl53I2cTransport::readMulti(uint16_t RegisterAddress, uint8_t *p data_write[0] = (RegisterAddress >> 8) & 0xFF; data_write[1] = RegisterAddress & 0xFF; - const auto status = I2cDevice::writeRead(&data_write[0], 2, p_values, size); + const auto status = this->writeRead(&data_write[0], 2, p_values, size); return static_cast(not status); }; @@ -135,13 +133,11 @@ uint8_t Vl53I2cTransport::readByte(uint16_t RegisterAddress, uint8_t *p_value) { uint8_t data_write[2]; - uint8_t data_read[1]; data_write[0] = (RegisterAddress >> 8) & 0xFF; data_write[1] = RegisterAddress & 0xFF; - const auto status = I2cDevice::writeRead(&data_write[0], 2, &data_read[0], 1); - *p_value = data_read[0]; + const auto status = this->writeRead(&data_write[0], 2, p_value, 1); return static_cast(not status); } @@ -150,13 +146,7 @@ template uint8_t Vl53I2cTransport::writeByte(uint16_t RegisterAddress, uint8_t value) { - uint8_t data_write[3]; - - data_write[0] = (RegisterAddress >> 8) & 0xFF; - data_write[1] = RegisterAddress & 0xFF; - data_write[2] = value & 0xFF; - - const auto status = I2cDevice::write(&data_write[0], 3); + const auto status = I2cEeprom::write(RegisterAddress, &value, 1); return static_cast(not status); }