diff --git a/drivers/sensor/CMakeLists.txt b/drivers/sensor/CMakeLists.txt index 087d33ce22455..5d000ac84dfbd 100644 --- a/drivers/sensor/CMakeLists.txt +++ b/drivers/sensor/CMakeLists.txt @@ -109,6 +109,7 @@ add_subdirectory_ifdef(CONFIG_TMP112 tmp112) add_subdirectory_ifdef(CONFIG_TMP116 tmp116) add_subdirectory_ifdef(CONFIG_VCNL4040 vcnl4040) add_subdirectory_ifdef(CONFIG_VL53L0X vl53l0x) +add_subdirectory_ifdef(CONFIG_VL53L1X vl53l1x) add_subdirectory_ifdef(CONFIG_TEMP_KINETIS nxp_kinetis_temp) add_subdirectory_ifdef(CONFIG_TACH_XEC mchp_tach_xec) add_subdirectory_ifdef(CONFIG_WSEN_HIDS wsen_hids) diff --git a/drivers/sensor/Kconfig b/drivers/sensor/Kconfig index 47c1ee1ee135d..11ae4f026563b 100644 --- a/drivers/sensor/Kconfig +++ b/drivers/sensor/Kconfig @@ -259,6 +259,8 @@ source "drivers/sensor/vcnl4040/Kconfig" source "drivers/sensor/vl53l0x/Kconfig" +source "drivers/sensor/vl53l1x/Kconfig" + source "drivers/sensor/nxp_kinetis_temp/Kconfig" source "drivers/sensor/wsen_hids/Kconfig" diff --git a/drivers/sensor/vl53l1x/CMakeLists.txt b/drivers/sensor/vl53l1x/CMakeLists.txt new file mode 100644 index 0000000000000..9df21487227b5 --- /dev/null +++ b/drivers/sensor/vl53l1x/CMakeLists.txt @@ -0,0 +1,8 @@ +# SPDX-License-Identifier: Apache-2.0 + +zephyr_library() + +zephyr_library_sources( + vl53l1.c + vl53l1_platform.c +) diff --git a/drivers/sensor/vl53l1x/Kconfig b/drivers/sensor/vl53l1x/Kconfig new file mode 100644 index 0000000000000..0865ff795496c --- /dev/null +++ b/drivers/sensor/vl53l1x/Kconfig @@ -0,0 +1,32 @@ +# VL53L0X time of flight sensor configuration options + +# Copyright (c) 2023 Prosaris Solutions Inc. +# SPDX-License-Identifier: Apache-2.0 + +menuconfig VL53L1X + bool "VL53L1X time of flight sensor" + default y + depends on DT_HAS_ST_VL53L1X_ENABLED + select I2C + select HAS_STLIB + help + Enable driver for VL53L1X I2C-based time of flight sensor. + +if VL53L1X + +config VL53L1X_INTERRUPT_MODE + bool "Use interrupt mode for VL53L1X time of flight sensor" + default y + depends on GPIO + help + Enable interrupt mode for VL53L1X time of flight sensor. Otherwise, + the driver will use the polling method. + +config VL53L1X_XSHUT + bool "Use xshut pin on VL53L1X time of flight sensor" + depends on GPIO + help + Enable to use the xshut pin on the VL53L1X. If not, the pin should be + connected to VDD. + +endif # VL53L1X diff --git a/drivers/sensor/vl53l1x/vl53l1.c b/drivers/sensor/vl53l1x/vl53l1.c new file mode 100644 index 0000000000000..34ae02e6869b5 --- /dev/null +++ b/drivers/sensor/vl53l1x/vl53l1.c @@ -0,0 +1,479 @@ +/* vl53l1.c - Driver for ST VL53L1X time of flight sensor */ + +/* + * Copyright (c) 2023 Prosaris SOlutions Inc. + * + * SPDX-License-Identifier: Apache-2.0 + */ + +#define DT_DRV_COMPAT st_vl53l1x + +#include + +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include "vl53l1_api.h" +#include "vl53l1_platform.h" + +LOG_MODULE_REGISTER(VL53L1X, CONFIG_SENSOR_LOG_LEVEL); + +struct vl53l1x_config { + struct i2c_dt_spec i2c; +#ifdef CONFIG_VL53L1X_XSHUT + struct gpio_dt_spec xshut; +#endif +#ifdef CONFIG_VL53L1X_INTERRUPT_MODE + struct gpio_dt_spec gpio1; +#endif +}; + +struct vl53l1x_data { + VL53L1_Dev_t vl53l1x; + VL53L1_RangingMeasurementData_t data; + VL53L1_DistanceModes distance_mode; +#ifdef CONFIG_VL53L1X_INTERRUPT_MODE + struct gpio_callback gpio_cb; + struct k_work work; + const struct device *dev; +#endif +}; + +static VL53L1_Error vl53l1x_read_sensor(struct vl53l1x_data *drv_data) +{ + VL53L1_Error ret; + + ret = VL53L1_GetRangingMeasurementData(&drv_data->vl53l1x, &drv_data->data); + if (ret != VL53L1_ERROR_NONE) { + LOG_ERR("VL53L1_GetRangingMeasurementData return error (%d)", ret); + return ret; + } + + ret = VL53L1_ClearInterruptAndStartMeasurement(&drv_data->vl53l1x); + if (ret != VL53L1_ERROR_NONE) { + LOG_ERR("VL53L1_ClearInterruptAndStartMeasurement return error (%d)", ret); + return ret; + } + + return VL53L1_ERROR_NONE; +} + +static void vl53l1x_worker(struct k_work *work) +{ + if (IS_ENABLED(CONFIG_VL53L1X_INTERRUPT_MODE)) { + struct vl53l1x_data *drv_data = CONTAINER_OF(work, struct vl53l1x_data, work); + + vl53l1x_read_sensor(drv_data); + } +} + +static void vl53l1x_gpio_callback(const struct device *dev, + struct gpio_callback *cb, uint32_t pins) +{ + if (IS_ENABLED(CONFIG_VL53L1X_INTERRUPT_MODE)) { + struct vl53l1x_data *drv_data = CONTAINER_OF(cb, struct vl53l1x_data, gpio_cb); + + k_work_submit(&drv_data->work); + } +} + +static int vl53l1x_init_interrupt(const struct device *dev) +{ + if (IS_ENABLED(CONFIG_VL53L1X_INTERRUPT_MODE)) { + struct vl53l1x_data *drv_data = dev->data; + const struct vl53l1x_config *config = dev->config; + int ret; + + drv_data->dev = dev; + + if (!device_is_ready(config->gpio1.port)) { + LOG_ERR("%s: device %s is not ready", dev->name, config->gpio1.port->name); + return -ENODEV; + } + + ret = gpio_pin_configure_dt(&config->gpio1, GPIO_INPUT | GPIO_PULL_UP); + if (ret < 0) { + LOG_ERR("[%s] Unable to configure GPIO interrupt", dev->name); + return -EIO; + } + + gpio_init_callback(&drv_data->gpio_cb, + vl53l1x_gpio_callback, + BIT(config->gpio1.pin)); + + ret = gpio_add_callback(config->gpio1.port, &drv_data->gpio_cb); + if (ret < 0) { + LOG_ERR("Failed to set gpio callback!"); + return -EIO; + } + + drv_data->work.handler = vl53l1x_worker; + } + return 0; +} + +static int vl53l1x_initialize(const struct device *dev) +{ + struct vl53l1x_data *drv_data = dev->data; + VL53L1_Error ret; + VL53L1_DeviceInfo_t vl53l1x_dev_info; + + LOG_DBG("[%s] Initializing ", dev->name); + + /* Pull XSHUT high to start the sensor */ +#ifdef CONFIG_VL53L1X_XSHUT + const struct vl53l1x_config *const config = dev->config; + + if (config->xshut.port) { + int gpio_ret = gpio_pin_set_dt(&config->xshut, 1); + + if (gpio_ret < 0) { + LOG_ERR("[%s] Unable to set XSHUT gpio (error %d)", dev->name, gpio_ret); + return -EIO; + } + /* Boot duration is 1.2 ms max */ + k_sleep(K_MSEC(2)); + } +#endif + + /* ONE TIME device initialization. + * To be called ONLY ONCE after device is brought out of reset + */ + ret = VL53L1_DataInit(&drv_data->vl53l1x); + if (ret != VL53L1_ERROR_NONE) { + LOG_ERR("[%s] VL53L1X_DataInit return error (%d)", dev->name, ret); + return -ENOTSUP; + } + + /* Do basic device init */ + ret = VL53L1_StaticInit(&drv_data->vl53l1x); + if (ret != VL53L1_ERROR_NONE) { + LOG_ERR("[%s] VL53L1_StaticInit return error (%d)", dev->name, ret); + return -ENOTSUP; + } + + /* Get info from sensor */ + (void)memset(&vl53l1x_dev_info, 0, sizeof(VL53L1_DeviceInfo_t)); + + ret = VL53L1_GetDeviceInfo(&drv_data->vl53l1x, &vl53l1x_dev_info); + if (ret != VL53L1_ERROR_NONE) { + LOG_ERR("[%s] VL53L1_GetDeviceInfo return error (%d)", dev->name, ret); + return -ENODEV; + } + + LOG_DBG("[%s] VL53L1X_GetDeviceInfo returned %d", dev->name, ret); + LOG_DBG(" Device Name : %s", vl53l1x_dev_info.Name); + LOG_DBG(" Device Type : %s", vl53l1x_dev_info.Type); + LOG_DBG(" Device ID : %s", vl53l1x_dev_info.ProductId); + LOG_DBG(" ProductRevisionMajor : %d", vl53l1x_dev_info.ProductRevisionMajor); + LOG_DBG(" ProductRevisionMinor : %d", vl53l1x_dev_info.ProductRevisionMinor); + + /* Set default distance mode */ + drv_data->distance_mode = VL53L1_DISTANCEMODE_LONG; + ret = VL53L1_SetDistanceMode(&drv_data->vl53l1x, drv_data->distance_mode); + if (ret != VL53L1_ERROR_NONE) { + LOG_ERR("[%s] VL53L1_SetDistanceMode return error (%d)", dev->name, ret); + return -EINVAL; + } + + return 0; +} + +/* Mapping is 1:1 with the API. + * From VL531X datasheet: + * | Max distance | Max distance in + * Mode | in dark (cm) | strong ambient light (cm) + * ---------------------------------------------------- + * short | 136 | 135 + * medium | 290 | 76 + * long | 360 | 73 + */ +static int vl53l1x_set_mode(const struct device *dev, + const struct sensor_value *val) +{ + struct vl53l1x_data *drv_data = dev->data; + VL53L1_Error ret; + + switch (val->val1) { + /* short */ + case 1: + /* medium */ + case 2: + /* long */ + case 3: + drv_data->distance_mode = val->val1; + break; + default: + drv_data->distance_mode = VL53L1_DISTANCEMODE_LONG; + break; + } + + ret = VL53L1_SetDistanceMode(&drv_data->vl53l1x, drv_data->distance_mode); + if (ret != VL53L1_ERROR_NONE) { + LOG_ERR("[%s] VL53L1_SetDistanceMode return error (%d)", dev->name, ret); + return -EINVAL; + } + + return 0; +} + +/* + * The ROI is a 16x16 grid. + * The bottom left is (0,0), top right is (15, 15), for + * a total of 256 squares (numbered 0 through 255). + * The default ROI is val1 = 240, val2 = 15 (the full grid). + * See UM2356 User Manual (VL531X API doc). + */ +static int vl53l1x_set_roi(const struct device *dev, + const struct sensor_value *val) +{ + struct vl53l1x_data *drv_data = dev->data; + VL53L1_Error ret; + + if ((val->val1 < 0) || + (val->val2 < 0) || + (val->val1 > 255) || + (val->val2 > 255) || + (val->val2 >= val->val1)) { + return -EINVAL; + } + + /* Map val to pUserROi */ + VL53L1_UserRoi_t pUserROi = { + .TopLeftX = val->val1 % 16, + .TopLeftY = (uint8_t)(val->val1 / 16), + .BotRightX = val->val2 % 16, + .BotRightY = (uint8_t)(val->val2 / 16), + }; + + ret = VL53L1_SetUserROI(&drv_data->vl53l1x, &pUserROi); + if (ret != VL53L1_ERROR_NONE) { + LOG_ERR("[%s] VL53L1_SetUserROI return error (%d)", dev->name, ret); + return -EINVAL; + } + + return 0; +} + +static int vl53l1x_get_mode(const struct device *dev, + struct sensor_value *val) +{ + struct vl53l1x_data *drv_data = dev->data; + VL53L1_DistanceModes mode; + VL53L1_Error ret; + + ret = VL53L1_GetDistanceMode(&drv_data->vl53l1x, &mode); + if (ret != VL53L1_ERROR_NONE) { + LOG_ERR("[%s] VL53L1_GetDistanceMode return error (%d)", dev->name, ret); + return -ENODATA; + } + + /* Mapping is 1:1 with the API */ + val->val1 = (int32_t)mode; + val->val2 = 0; + return 0; +} + +static int vl53l1x_get_roi(const struct device *dev, + struct sensor_value *val) +{ + struct vl53l1x_data *drv_data = dev->data; + VL53L1_Error ret; + VL53L1_UserRoi_t pUserROi; + + ret = VL53L1_GetUserROI(&drv_data->vl53l1x, &pUserROi); + if (ret != VL53L1_ERROR_NONE) { + LOG_ERR("[%s] VL53L1_GetUserROI return error (%d)", dev->name, ret); + return -ENODATA; + } + + /* Map pUserROi to val */ + val->val1 = (int32_t)((16 * pUserROi.TopLeftY) + pUserROi.TopLeftX); + val->val2 = (int32_t)((16 * pUserROi.BotRightY) + pUserROi.BotRightX); + return 0; +} + +static int vl53l1x_sample_fetch(const struct device *dev, + enum sensor_channel chan) +{ + struct vl53l1x_data *drv_data = dev->data; + const struct vl53l1x_config *config = dev->config; + VL53L1_Error ret; + + __ASSERT_NO_MSG(chan == SENSOR_CHAN_DISTANCE); + + /* Will immediately stop current measurement */ + ret = VL53L1_StopMeasurement(&drv_data->vl53l1x); + if (ret != VL53L1_ERROR_NONE) { + LOG_ERR("VL53L1_StopMeasurement return error (%d)", ret); + return -EBUSY; + } + + if (IS_ENABLED(CONFIG_VL53L1X_INTERRUPT_MODE)) { + ret = gpio_pin_interrupt_configure_dt(&config->gpio1, GPIO_INT_EDGE_TO_INACTIVE); + if (ret < 0) { + LOG_ERR("[%s] Unable to config interrupt", dev->name); + return -EIO; + } + } + + ret = VL53L1_StartMeasurement(&drv_data->vl53l1x); + if (ret != VL53L1_ERROR_NONE) { + LOG_ERR("[%s] VL53L1_StartMeasurement return error (%d)", dev->name, ret); + return -EBUSY; + } + + return 0; +} + +static int vl53l1x_channel_get(const struct device *dev, + enum sensor_channel chan, + struct sensor_value *val) +{ + struct vl53l1x_data *drv_data = dev->data; + VL53L1_Error ret; + + __ASSERT_NO_MSG(chan == SENSOR_CHAN_DISTANCE); + + /* Calling VL53L1_WaitMeasurementDataReady regardless of using interrupt or + * polling method ensures user does not have to consider the time between + * calling fetch and get. + */ + ret = VL53L1_WaitMeasurementDataReady(&drv_data->vl53l1x); + if (ret != VL53L1_ERROR_NONE) { + LOG_ERR("[%s] VL53L1_WaitMeasurementDataReady return error (%d)", dev->name, ret); + return -EBUSY; + } + + if (IS_ENABLED(CONFIG_VL53L1X_INTERRUPT_MODE) == 0) { + /* Using driver poling mode */ + ret = vl53l1x_read_sensor(drv_data); + if (ret != VL53L1_ERROR_NONE) { + return -ENODATA; + } + } + + val->val1 = (int32_t)(drv_data->data.RangeMilliMeter); + /* RangeFractionalPart not implemented in API */ + val->val2 = 0; + + return 0; +} + +static int vl53l1x_attr_get(const struct device *dev, + enum sensor_channel chan, + enum sensor_attribute attr, + struct sensor_value *val) +{ + __ASSERT_NO_MSG(chan == SENSOR_CHAN_DISTANCE); + + if (attr == SENSOR_ATTR_CONFIGURATION) { + vl53l1x_get_mode(dev, val); + } else if (attr == SENSOR_ATTR_CALIB_TARGET) { + vl53l1x_get_roi(dev, val); + } else { + return -ENOTSUP; + } + + return 0; +} + +static int vl53l1x_attr_set(const struct device *dev, + enum sensor_channel chan, + enum sensor_attribute attr, + const struct sensor_value *val) +{ + __ASSERT_NO_MSG(chan == SENSOR_CHAN_DISTANCE); + + if (attr == SENSOR_ATTR_CONFIGURATION) { + vl53l1x_set_mode(dev, val); + } else if (attr == SENSOR_ATTR_CALIB_TARGET) { + vl53l1x_set_roi(dev, val); + } else { + return -ENOTSUP; + } + + return 0; +} + +static const struct sensor_driver_api vl53l1x_api_funcs = { + .sample_fetch = vl53l1x_sample_fetch, + .channel_get = vl53l1x_channel_get, + .attr_get = vl53l1x_attr_get, + .attr_set = vl53l1x_attr_set, +}; + +static int vl53l1x_init(const struct device *dev) +{ + int ret = 0; + struct vl53l1x_data *drv_data = dev->data; + const struct vl53l1x_config *config = dev->config; + + /* Initialize the HAL i2c peripheral */ + drv_data->vl53l1x.i2c = &config->i2c; + + if (!device_is_ready(config->i2c.bus)) { + LOG_ERR("I2C bus is not ready"); + return -ENODEV; + } + + /* Configure gpio connected to VL53L1X's XSHUT pin to + * allow deepest sleep mode + */ +#ifdef CONFIG_VL53L1X_XSHUT + if (config->xshut.port) { + ret = gpio_pin_configure_dt(&config->xshut, GPIO_OUTPUT); + if (ret < 0) { + LOG_ERR("[%s] Unable to configure GPIO as output", dev->name); + return -EIO; + } + } +#endif + +#ifdef CONFIG_VL53L1X_INTERRUPT_MODE + if (config->gpio1.port) { + ret = vl53l1x_init_interrupt(dev); + if (ret < 0) { + LOG_ERR("Failed to initialize interrupt!"); + return -EIO; + } + } +#endif + + ret = vl53l1x_initialize(dev); + if (ret) { + return ret; + } + + LOG_DBG("[%s] Initialized", dev->name); + return 0; +} + +#define VL53L1X_INIT(i) \ + static const struct vl53l1x_config vl53l1x_config_##i = { \ + .i2c = I2C_DT_SPEC_INST_GET(i), \ + IF_ENABLED(CONFIG_VL53L1X_XSHUT, ( \ + .xshut = GPIO_DT_SPEC_INST_GET_OR(i, xshut_gpios, { 0 }),)) \ + IF_ENABLED(CONFIG_VL53L1X_INTERRUPT_MODE, ( \ + .gpio1 = GPIO_DT_SPEC_INST_GET_OR(i, int_gpios, { 0 }),)) \ + }; \ + \ + static struct vl53l1x_data vl53l1x_data_##i; \ + \ + SENSOR_DEVICE_DT_INST_DEFINE(i, \ + vl53l1x_init, \ + NULL, \ + &vl53l1x_data_##i, \ + &vl53l1x_config_##i, \ + POST_KERNEL, \ + CONFIG_SENSOR_INIT_PRIORITY, \ + &vl53l1x_api_funcs); + +DT_INST_FOREACH_STATUS_OKAY(VL53L1X_INIT) diff --git a/drivers/sensor/vl53l1x/vl53l1_platform.c b/drivers/sensor/vl53l1x/vl53l1_platform.c new file mode 100644 index 0000000000000..a3e02b5466ade --- /dev/null +++ b/drivers/sensor/vl53l1x/vl53l1_platform.c @@ -0,0 +1,182 @@ +/* vl53l1_platform.c - Zephyr customization of ST vl53l1x library. + */ + +/* + * Copyright (c) 2023 Prosaris Solutions Inc. + * + * SPDX-License-Identifier: Apache-2.0 + */ + +#include "vl53l1_platform.h" +#include "vl53l1_platform_log.h" + +#include +#include +#include +#include +#include +#include +#include + +LOG_MODULE_DECLARE(VL53L1X, CONFIG_SENSOR_LOG_LEVEL); + +VL53L1_Error VL53L1_WriteMulti(VL53L1_Dev_t *pdev, uint16_t reg, + uint8_t *pdata, uint32_t count) +{ + VL53L1_Error status = VL53L1_ERROR_NONE; + int32_t status_int = 0; + uint8_t buffer[count + 2]; + + /* To be able to write to the 16-bit registers/addresses on the vl53l1x */ + buffer[1] = (uint8_t)(reg & 0x00ff); + buffer[0] = (uint8_t)((reg & 0xff00) >> 8); + + memcpy(&buffer[2], pdata, count); + + status_int = i2c_write_dt(pdev->i2c, buffer, count + 2); + + if (status_int < 0) { + status = VL53L1_ERROR_CONTROL_INTERFACE; + LOG_ERR("Failed to write"); + } + + return status; +} + +VL53L1_Error VL53L1_ReadMulti(VL53L1_Dev_t *pdev, uint16_t reg, + uint8_t *pdata, uint32_t count) +{ + VL53L1_Error status = VL53L1_ERROR_NONE; + int32_t status_int = 0; + + reg = sys_cpu_to_be16(reg); + + status_int = i2c_write_read_dt(pdev->i2c, (uint8_t *)(®), 2, pdata, count); + + if (status_int < 0) { + status = VL53L1_ERROR_CONTROL_INTERFACE; + LOG_ERR("Failed to read"); + return -EIO; + } + + return status; +} + +VL53L1_Error VL53L1_WrByte(VL53L1_Dev_t *pdev, uint16_t reg, uint8_t data) +{ + VL53L1_Error status = VL53L1_ERROR_NONE; + + status = VL53L1_WriteMulti(pdev, reg, &data, 1); + + return status; +} + +VL53L1_Error VL53L1_WrWord(VL53L1_Dev_t *pdev, uint16_t reg, uint16_t data) +{ + VL53L1_Error status = VL53L1_ERROR_NONE; + + data = sys_cpu_to_be16(data); + + status = VL53L1_WriteMulti(pdev, reg, (uint8_t *)(&data), VL53L1_BYTES_PER_WORD); + + return status; +} + +VL53L1_Error VL53L1_WrDWord(VL53L1_Dev_t *pdev, uint16_t reg, uint32_t data) +{ + VL53L1_Error status = VL53L1_ERROR_NONE; + + data = sys_cpu_to_be32(data); + + status = VL53L1_WriteMulti(pdev, reg, (uint8_t *)(&data), VL53L1_BYTES_PER_DWORD); + + return status; +} + +VL53L1_Error VL53L1_RdByte(VL53L1_Dev_t *pdev, uint16_t reg, uint8_t *pdata) +{ + VL53L1_Error status = VL53L1_ERROR_NONE; + + status = VL53L1_ReadMulti(pdev, reg, pdata, 1); + + return status; +} + +VL53L1_Error VL53L1_RdWord(VL53L1_Dev_t *pdev, uint16_t reg, uint16_t *pdata) +{ + VL53L1_Error status = VL53L1_ERROR_NONE; + + status = VL53L1_ReadMulti(pdev, reg, (uint8_t *)pdata, 2); + *pdata = sys_be16_to_cpu(*pdata); + + return status; +} + +VL53L1_Error VL53L1_RdDWord(VL53L1_Dev_t *pdev, uint16_t reg, uint32_t *pdata) +{ + VL53L1_Error status = VL53L1_ERROR_NONE; + + status = VL53L1_ReadMulti(pdev, reg, (uint8_t *)pdata, 4); + *pdata = sys_be32_to_cpu(*pdata); + + return status; +} + +VL53L1_Error VL53L1_WaitUs(VL53L1_Dev_t *pdev, int32_t wait_us) +{ + k_sleep(K_USEC(wait_us)); + return VL53L1_ERROR_NONE; +} + +VL53L1_Error VL53L1_WaitMs(VL53L1_Dev_t *pdev, int32_t wait_ms) +{ + return VL53L1_WaitUs(pdev, wait_ms * 1000); +} + +VL53L1_Error VL53L1_GetTickCount(uint32_t *ptick_count_ms) +{ + *ptick_count_ms = k_uptime_get_32(); + return VL53L1_ERROR_NONE; +} + +VL53L1_Error VL53L1_WaitValueMaskEx(VL53L1_Dev_t *dev, uint32_t timeout, uint16_t i, uint8_t val, + uint8_t mask, uint32_t delay) +{ + VL53L1_Error status = VL53L1_ERROR_NONE; + uint32_t start_time_ms = 0; + uint32_t current_time_ms = 0; + uint8_t byte_val = 0; + uint8_t found = 0; + + /* calculate time limit in absolute time */ + VL53L1_GetTickCount(&start_time_ms); + dev->new_data_ready_poll_duration_ms = 0; + + /* wait until val is found, timeout reached on error occurred */ + while ((status == VL53L1_ERROR_NONE) && + (dev->new_data_ready_poll_duration_ms < timeout) && + (found == 0)) { + status = VL53L1_RdByte(dev, i, &byte_val); + + if ((byte_val & mask) == val) { + found = 1; + } + + if ((status == VL53L1_ERROR_NONE) && (found == 0) && (delay > 0)) { + /* Allow for other threads to run */ + status = VL53L1_WaitMs(dev, delay); + } + + /* Update polling time (Compare difference rather than absolute to + * negate 32bit wrap around issue) + */ + VL53L1_GetTickCount(¤t_time_ms); + dev->new_data_ready_poll_duration_ms = current_time_ms - start_time_ms; + } + + if (found == 0 && status == VL53L1_ERROR_NONE) { + status = VL53L1_ERROR_TIME_OUT; + } + + return status; +} diff --git a/drivers/sensor/vl53l1x/vl53l1_platform.h b/drivers/sensor/vl53l1x/vl53l1_platform.h new file mode 100644 index 0000000000000..8b1b2a0f37f46 --- /dev/null +++ b/drivers/sensor/vl53l1x/vl53l1_platform.h @@ -0,0 +1,149 @@ +/* vl53l1_platform.h - Zephyr customization of ST vl53l1x library. */ + +/* + * Copyright (c) 2017 STMicroelectronics + * + * SPDX-License-Identifier: Apache-2.0 + */ + +#ifndef ZEPHYR_DRIVERS_SENSOR_VL53L1X_VL53L1_PLATFORM_H_ +#define ZEPHYR_DRIVERS_SENSOR_VL53L1X_VL53L1_PLATFORM_H_ + +#include +#include "vl53l1_ll_def.h" +#include "vl53l1_platform_log.h" +#include "vl53l1_platform_user_data.h" + +#ifdef __cplusplus +extern "C" { +#endif + +/** + * Writes the supplied byte buffer to the device + * @param pdev Pointer to device structure (device handle) + * @param index Register index value + * @param pdata Pointer to uint8_t (byte) buffer containing the data to be written + * @param count Number of bytes in the supplied byte buffer + * @return VL53L1_ERROR_NONE Success + * @return "Other error code" See ::VL53L1_Error + */ +VL53L1_Error VL53L1_WriteMulti(VL53L1_Dev_t *pdev, uint16_t index, + uint8_t *pdata, uint32_t count); + +/** + * Reads the requested number of bytes from the device + * @param pdev Pointer to device structure (device handle) + * @param index Register index value + * @param pdata Pointer to the uint8_t (byte) buffer to store read data + * @param count Number of bytes to read + * @return VL53L1_ERROR_NONE Success + * @return "Other error code" See ::VL53L1_Error + */ +VL53L1_Error VL53L1_ReadMulti(VL53L1_Dev_t *pdev, uint16_t index, + uint8_t *pdata, uint32_t count); + +/** + * Writes a single byte to the device + * @param pdev Pointer to device structure (device handle) + * @param index Register index value + * @param data Data value to write + * @return VL53L1_ERROR_NONE Success + * @return "Other error code" See ::VL53L1_Error + */ +VL53L1_Error VL53L1_WrByte(VL53L1_Dev_t *pdev, uint16_t index, uint8_t data); + +/** + * Writes a single word (16-bit unsigned) to the device + * @param pdev Pointer to device structure (device handle) + * @param index Register index value + * @param data Data value write + * @return VL53L1_ERROR_NONE Success + * @return "Other error code" See ::VL53L1_Error + */ +VL53L1_Error VL53L1_WrWord(VL53L1_Dev_t *pdev, uint16_t index, uint16_t data); + +/** + * Writes a single dword (32-bit unsigned) to the device + * @param pdev Pointer to device structure (device handle) + * @param index Register index value + * @param data Data value to write + * @return VL53L1_ERROR_NONE Success + * @return "Other error code" See ::VL53L1_Error + */ +VL53L1_Error VL53L1_WrDWord(VL53L1_Dev_t *pdev, uint16_t index, uint32_t data); + +/** + * Reads a single byte from the device + * @param pdev Pointer to device structure (device handle) + * @param index Register index + * @param pdata Pointer to uint8_t data value + * @return VL53L1_ERROR_NONE Success + * @return "Other error code" See ::VL53L1_Error + */ +VL53L1_Error VL53L1_RdByte(VL53L1_Dev_t *pdev, uint16_t index, uint8_t *pdata); + +/** + * Reads a single word (16-bit unsigned) from the device + * @param pdev Pointer to device structure (device handle) + * @param index Register index value + * @param pdata Pointer to uint16_t data value + * @return VL53L1_ERROR_NONE Success + * @return "Other error code" See ::VL53L1_Error + */ +VL53L1_Error VL53L1_RdWord(VL53L1_Dev_t *pdev, uint16_t index, uint16_t *pdata); + +/** + * Reads a single double word (32-bit unsigned) from the device + * @param pdev Pointer to device structure (device handle) + * @param index Register index value + * @param pdata Pointer to uint32_t data value + * @return VL53L1_ERROR_NONE Success + * @return "Other error code" See ::VL53L1_Error + */ +VL53L1_Error VL53L1_RdDWord(VL53L1_Dev_t *pdev, uint16_t index, uint32_t *pdata); + +/** + * Implements a programmable wait in us + * @param pdev Pointer to device structure (device handle) + * @param wait_us Integer wait in micro seconds + * @return VL53L1_ERROR_NONE Success + * @return "Other error code" See ::VL53L1_Error + */ +VL53L1_Error VL53L1_WaitUs(VL53L1_Dev_t *pdev, int32_t wait_us); + +/** + * Implements a programmable wait in ms + * @param pdev Pointer to device structure (device handle) + * @param wait_ms Integer wait in milliseconds + * @return VL53L1_ERROR_NONE Success + * @return "Other error code" See ::VL53L1_Error + */ +VL53L1_Error VL53L1_WaitMs(VL53L1_Dev_t *pdev, int32_t wait_ms); + +/** + * Gets current system tick count in [ms] + * @param Pointer to current time in [ms] + * @return VL53L1_ERROR_NONE Success + * @return "Other error code" See ::VL53L1_Error + */ +VL53L1_Error VL53L1_GetTickCount(uint32_t *ptime_ms); + +/** + * Register "wait for value" polling routine + * @param dev Pointer to device structure (device handle) + * @param timeout Timeout in [ms] + * @param i Register index value + * @param val Value to wait for + * @param mask Mask to be applied before comparison with value + * @param delay Polling delay between each read transaction in [ms] + * @return VL53L1_ERROR_NONE Success + * @return "Other error code" See ::VL53L1_Error + */ +VL53L1_Error VL53L1_WaitValueMaskEx(VL53L1_Dev_t *dev, uint32_t timeout, uint16_t i, uint8_t val, + uint8_t mask, uint32_t delay); + +#ifdef __cplusplus +} +#endif + +#endif diff --git a/drivers/sensor/vl53l1x/vl53l1_platform_log.h b/drivers/sensor/vl53l1x/vl53l1_platform_log.h new file mode 100644 index 0000000000000..57019e42ba02c --- /dev/null +++ b/drivers/sensor/vl53l1x/vl53l1_platform_log.h @@ -0,0 +1,200 @@ +/* vl53l1x_platform_log.h - Zephyr customization of ST vl53l1x library. */ + +/* + * Copyright (c) 2017 STMicroelectronics + * + * SPDX-License-Identifier: Apache-2.0 + */ + + +#ifndef _VL53L1_PLATFORM_LOG_H_ +#define _VL53L1_PLATFORM_LOG_H_ + + +#ifdef VL53L1_LOG_ENABLE + #include "vl53l1_platform_user_config.h" + + #ifdef _MSC_VER + # define EWOKPLUS_EXPORTS __declspec(dllexport) + #else + # define EWOKPLUS_EXPORTS + #endif + + #include "vl53l1_types.h" + + #ifdef __cplusplus + extern "C" { + #endif + + #include + + /** + * @brief Set the level, output and specific functions for module logging. + * + * + * @param filename - full path of output log file, NULL for print to stdout + * + * @param modules - Module or None or All to trace + * VL53L1_TRACE_MODULE_NONE + * VL53L1_TRACE_MODULE_API + * VL53L1_TRACE_MODULE_CORE + * VL53L1_TRACE_MODULE_TUNING + * VL53L1_TRACE_MODULE_CHARACTERISATION + * VL53L1_TRACE_MODULE_PLATFORM + * VL53L1_TRACE_MODULE_ALL + * + * @param level - trace level + * VL53L1_TRACE_LEVEL_NONE + * VL53L1_TRACE_LEVEL_ERRORS + * VL53L1_TRACE_LEVEL_WARNING + * VL53L1_TRACE_LEVEL_INFO + * VL53L1_TRACE_LEVEL_DEBUG + * VL53L1_TRACE_LEVEL_ALL + * VL53L1_TRACE_LEVEL_IGNORE + * + * @param functions - function level to trace; + * VL53L1_TRACE_FUNCTION_NONE + * VL53L1_TRACE_FUNCTION_I2C + * VL53L1_TRACE_FUNCTION_ALL + * + * @return status - always VL53L1_ERROR_NONE + * + */ + + #define VL53L1_TRACE_LEVEL_NONE 0x00000000 + #define VL53L1_TRACE_LEVEL_ERRORS 0x00000001 + #define VL53L1_TRACE_LEVEL_WARNING 0x00000002 + #define VL53L1_TRACE_LEVEL_INFO 0x00000004 + #define VL53L1_TRACE_LEVEL_DEBUG 0x00000008 + #define VL53L1_TRACE_LEVEL_ALL 0x00000010 + #define VL53L1_TRACE_LEVEL_IGNORE 0x00000020 + + #define VL53L1_TRACE_FUNCTION_NONE 0x00000000 + #define VL53L1_TRACE_FUNCTION_I2C 0x00000001 + #define VL53L1_TRACE_FUNCTION_ALL 0x7fffffff + + #define VL53L1_TRACE_MODULE_NONE 0x00000000 + #define VL53L1_TRACE_MODULE_API 0x00000001 + #define VL53L1_TRACE_MODULE_CORE 0x00000002 + #define VL53L1_TRACE_MODULE_PROTECTED 0x00000004 + #define VL53L1_TRACE_MODULE_HISTOGRAM 0x00000008 + #define VL53L1_TRACE_MODULE_REGISTERS 0x00000010 + #define VL53L1_TRACE_MODULE_PLATFORM 0x00000020 + #define VL53L1_TRACE_MODULE_NVM 0x00000040 + #define VL53L1_TRACE_MODULE_CALIBRATION_DATA 0x00000080 + #define VL53L1_TRACE_MODULE_NVM_DATA 0x00000100 + #define VL53L1_TRACE_MODULE_HISTOGRAM_DATA 0x00000200 + #define VL53L1_TRACE_MODULE_RANGE_RESULTS_DATA 0x00000400 + #define VL53L1_TRACE_MODULE_XTALK_DATA 0x00000800 + #define VL53L1_TRACE_MODULE_OFFSET_DATA 0x00001000 + #define VL53L1_TRACE_MODULE_DATA_INIT 0x00002000 + #define VL53L1_TRACE_MODULE_REF_SPAD_CHAR 0x00004000 + #define VL53L1_TRACE_MODULE_SPAD_RATE_MAP 0x00008000 +#ifdef PAL_EXTENDED + #define VL53L1_TRACE_MODULE_SPAD 0x01000000 + #define VL53L1_TRACE_MODULE_FMT 0x02000000 + #define VL53L1_TRACE_MODULE_UTILS 0x04000000 + #define VL53L1_TRACE_MODULE_BENCH_FUNCS 0x08000000 +#endif + #define VL53L1_TRACE_MODULE_CUSTOMER_API 0x40000000 + #define VL53L1_TRACE_MODULE_ALL 0x7fffffff + + + extern uint32_t _trace_level; + + /* + * NOTE: dynamically exported if we enable logging. + * this way, Python interfaces can access this function, but we don't + * need to include it in the .def files. + */ + EWOKPLUS_EXPORTS int8_t VL53L1_trace_config( + char *filename, + uint32_t modules, + uint32_t level, + uint32_t functions); + + /** + * @brief Print trace module function. + * + * @param module - ?? + * @param level - ?? + * @param function - ?? + * @param format - ?? + * + */ + + EWOKPLUS_EXPORTS void VL53L1_trace_print_module_function( + uint32_t module, + uint32_t level, + uint32_t function, + const char *format, ...); + + /** + * @brief Get global _trace_functions parameter + * + * @return _trace_functions + */ + + uint32_t VL53L1_get_trace_functions(void); + + /** + * @brief Set global _trace_functions parameter + * + * @param[in] function : new function code + */ + + void VL53L1_set_trace_functions(uint32_t function); + + + /* + * @brief Returns the current system tick count in [ms] + * + * @return time_ms : current time in [ms] + * + */ + + uint32_t VL53L1_clock(void); + + #define LOG_GET_TIME() \ + ((int)VL53L1_clock()) + + #define _LOG_TRACE_PRINT(module, level, function, ...) \ + VL53L1_trace_print_module_function(module, level, function, ##__VA_ARGS__); + + #define _LOG_FUNCTION_START(module, fmt, ...) \ + VL53L1_trace_print_module_function(module, _trace_level, VL53L1_TRACE_FUNCTION_ALL,\ + "%6ld %s "fmt"\n", LOG_GET_TIME(), __func__, ##__VA_ARGS__); + + #define _LOG_FUNCTION_END(module, status, ...)\ + VL53L1_trace_print_module_function(module, _trace_level, VL53L1_TRACE_FUNCTION_ALL,\ + "%6ld %s %d\n", LOG_GET_TIME(), __func__, (int)status, ##__VA_ARGS__) + + #define _LOG_FUNCTION_END_FMT(module, status, fmt, ...)\ + VL53L1_trace_print_module_function(module, _trace_level, VL53L1_TRACE_FUNCTION_ALL,\ + "%6ld %s %d "fmt"\n", LOG_GET_TIME(), __func__, (int)status, ##__VA_ARGS__) + + #define _LOG_GET_TRACE_FUNCTIONS()\ + VL53L1_get_trace_functions() + + #define _LOG_SET_TRACE_FUNCTIONS(functions)\ + VL53L1_set_trace_functions(functions) + + #define _LOG_STRING_BUFFER(x) char x[VL53L1_MAX_STRING_LENGTH] + + #ifdef __cplusplus + } + #endif + +#else /* VL53L1_LOG_ENABLE - no logging */ + + #define _LOG_TRACE_PRINT(module, level, function, ...) + #define _LOG_FUNCTION_START(module, fmt, ...) + #define _LOG_FUNCTION_END(module, status, ...) + #define _LOG_FUNCTION_END_FMT(module, status, fmt, ...) + #define _LOG_GET_TRACE_FUNCTIONS() 0 + #define _LOG_SET_TRACE_FUNCTIONS(functions) + #define _LOG_STRING_BUFFER(x) + +#endif /* VL53L1_LOG_ENABLE */ + +#endif /* _VL53L1_PLATFORM_LOG_H_ */ diff --git a/drivers/sensor/vl53l1x/vl53l1_platform_user_config.h b/drivers/sensor/vl53l1x/vl53l1_platform_user_config.h new file mode 100644 index 0000000000000..02b655437b47c --- /dev/null +++ b/drivers/sensor/vl53l1x/vl53l1_platform_user_config.h @@ -0,0 +1,61 @@ +/* vl53l1x_platform_user_config.h - Zephyr customization of ST vl53l1x library. */ + +/* + * Copyright (c) 2017 STMicroelectronics + * + * SPDX-License-Identifier: Apache-2.0 + */ + +#ifndef _VL53L1_PLATFORM_USER_CONFIG_H_ +#define _VL53L1_PLATFORM_USER_CONFIG_H_ + +#define VL53L1_BYTES_PER_WORD 2 +#define VL53L1_BYTES_PER_DWORD 4 + +/* Define polling delays */ +#define VL53L1_BOOT_COMPLETION_POLLING_TIMEOUT_MS 500 +#define VL53L1_RANGE_COMPLETION_POLLING_TIMEOUT_MS 2000 +#define VL53L1_TEST_COMPLETION_POLLING_TIMEOUT_MS 60000 + +#define VL53L1_POLLING_DELAY_MS 1 + +/* Define LLD TuningParms Page Base Address + * - Part of Patch_AddedTuningParms_11761 + */ +#define VL53L1_TUNINGPARM_PUBLIC_PAGE_BASE_ADDRESS 0x8000 +#define VL53L1_TUNINGPARM_PRIVATE_PAGE_BASE_ADDRESS 0xC000 + +#define VL53L1_GAIN_FACTOR__STANDARD_DEFAULT 0x0800 + /*!< Default standard ranging gain correction factor + * 1.11 format. 1.0 = 0x0800, 0.980 = 0x07D7 + */ + +#define VL53L1_OFFSET_CAL_MIN_EFFECTIVE_SPADS 0x0500 + /*!< Lower Limit for the MM1 effective SPAD count during offset + * calibration Format 8.8 0x0500 -> 5.0 effective SPADs + */ + +#define VL53L1_OFFSET_CAL_MAX_PRE_PEAK_RATE_MCPS 0x1900 + /*!< Max Limit for the pre range peak rate during offset + * calibration Format 9.7 0x1900 -> 50.0 Mcps. + * If larger then in pile up + */ + +#define VL53L1_OFFSET_CAL_MAX_SIGMA_MM 0x0040 + /*!< Max sigma estimate limit during offset calibration + * Check applies to pre-range, mm1 and mm2 ranges + * Format 14.2 0x0040 -> 16.0mm. + */ + +#define VL53L1_MAX_USER_ZONES 1 + /*!< Max number of user Zones - maximal limitation from + * FW stream divide - value of 254 + */ + +#define VL53L1_MAX_RANGE_RESULTS 2 + /*!< Allocates storage for return and reference restults */ + + +#define VL53L1_MAX_STRING_LENGTH 512 + +#endif /* _VL53L1_PLATFORM_USER_CONFIG_H_ */ diff --git a/drivers/sensor/vl53l1x/vl53l1_platform_user_data.h b/drivers/sensor/vl53l1x/vl53l1_platform_user_data.h new file mode 100644 index 0000000000000..211265ca26c53 --- /dev/null +++ b/drivers/sensor/vl53l1x/vl53l1_platform_user_data.h @@ -0,0 +1,83 @@ +/* vl53l1_platform_user_data.h - Zephyr customization of ST vl53l1x library. */ + +/* + * Copyright (c) 2017 STMicroelectronics + * + * SPDX-License-Identifier: Apache-2.0 + */ + +#ifndef ZEPHYR_DRIVERS_SENSOR_VL53L1X_VL53L1_PLATFORM_USER_DATA_H_ +#define ZEPHYR_DRIVERS_SENSOR_VL53L1X_VL53L1_PLATFORM_USER_DATA_H_ + +#include "vl53l1_def.h" + +#ifdef __cplusplus +extern "C" { +#endif + +/** + * @struct VL53L1_Dev_t + * @brief Generic PAL device type that does link between API and platform + * abstraction layer + * + */ +typedef struct { + /*!< Low Level Driver data structure */ + VL53L1_DevData_t Data; + /*!< New data ready poll duration in ms - for debug */ + uint32_t new_data_ready_poll_duration_ms; + /*!< I2C device handle */ + const struct i2c_dt_spec *i2c; +} VL53L1_Dev_t; + + +/** + * @brief Declare the device Handle as a pointer of the structure @a VL53L1_Dev_t. + * + */ +typedef VL53L1_Dev_t *VL53L1_DEV; + +/** + * @def VL53L1PALDevDataGet + * @brief Get ST private structure @a VL53L1_DevData_t data access + * + * @param Dev Device Handle + * @param field ST structure field name + * It maybe used and as real data "ref" not just as "get" for sub-structure item + * like PALDevDataGet(FilterData.field)[i] or + * PALDevDataGet(FilterData.MeasurementIndex)++ + */ +#define VL53L1DevDataGet(Dev, field) (Dev->Data.field) + + +/** + * @def VL53L1PALDevDataSet(Dev, field, data) + * @brief Set ST private structure @a VL53L1_DevData_t data field + * @param Dev Device Handle + * @param field ST structure field name + * @param data Data to be set + */ +#define VL53L1DevDataSet(Dev, field, data) ((Dev->Data.field) = (data)) + + +/** + * @def VL53L1DevStructGetLLDriverHandle + * @brief Get LL Driver handle @a VL53L0_Dev_t data access + * + * @param Dev Device Handle + */ +#define VL53L1DevStructGetLLDriverHandle(Dev) (&Dev->Data.LLData) + +/** + * @def VL53L1DevStructGetLLResultsHandle + * @brief Get LL Results handle @a VL53L0_Dev_t data access + * + * @param Dev Device Handle + */ +#define VL53L1DevStructGetLLResultsHandle(Dev) (&Dev->Data.llresults) + +#ifdef __cplusplus +} +#endif + +#endif /*ZEPHYR_DRIVERS_SENSOR_VL53L1X_VL53L1_PLATFORM_USER_DATA_H_*/ diff --git a/drivers/sensor/vl53l1x/vl53l1_platform_user_defines.h b/drivers/sensor/vl53l1x/vl53l1_platform_user_defines.h new file mode 100644 index 0000000000000..c5caaac14a1b3 --- /dev/null +++ b/drivers/sensor/vl53l1x/vl53l1_platform_user_defines.h @@ -0,0 +1,73 @@ +/* vl53l1x_platform_user_defines.h - Zephyr customization of ST vl53l1x library. */ + +/* + * Copyright (c) 2017 STMicroelectronics + * + * SPDX-License-Identifier: Apache-2.0 + */ + +#ifndef _VL53L1_PLATFORM_USER_DEFINES_H_ +#define _VL53L1_PLATFORM_USER_DEFINES_H_ + +#ifdef __cplusplus +extern "C" +{ +#endif + +/** + * @file vl53l1_platform_user_defines.h + * + * @brief All end user OS/platform/application definitions + */ + + +/** + * @def do_division_u + * @brief customer supplied division operation - 64-bit unsigned + * + * @param dividend unsigned 64-bit numerator + * @param divisor unsigned 64-bit denominator + */ +#define do_division_u(dividend, divisor) (dividend / divisor) + + +/** + * @def do_division_s + * @brief customer supplied division operation - 64-bit signed + * + * @param dividend signed 64-bit numerator + * @param divisor signed 64-bit denominator + */ +#define do_division_s(dividend, divisor) (dividend / divisor) + + +/** + * @def WARN_OVERRIDE_STATUS + * @brief customer supplied macro to optionally output info when a specific + error has been overridden with success within the EwokPlus driver + * + * @param __X__ the macro which enabled the suppression + */ +#define WARN_OVERRIDE_STATUS(__X__)\ + trace_print(VL53L1_TRACE_LEVEL_WARNING, #__X__); + + +#ifdef _MSC_VER +#define DISABLE_WARNINGS() { \ + __pragma(warning(push)); \ + __pragma(warning(disable:4127)); \ + } +#define ENABLE_WARNINGS() { \ + __pragma(warning(pop)); \ + } +#else + #define DISABLE_WARNINGS() + #define ENABLE_WARNINGS() +#endif + + +#ifdef __cplusplus +} +#endif + +#endif diff --git a/drivers/sensor/vl53l1x/vl53l1_types.h b/drivers/sensor/vl53l1x/vl53l1_types.h new file mode 100644 index 0000000000000..bd8cd18606290 --- /dev/null +++ b/drivers/sensor/vl53l1x/vl53l1_types.h @@ -0,0 +1,30 @@ +/* vl53l1_types.h - Zephyr customization of ST vl53l1x library, basic type definition. */ + +/* + * Copyright (c) 2017 STMicroelectronics + * + * SPDX-License-Identifier: Apache-2.0 + */ + +#ifndef ZEPHYR_DRIVERS_SENSOR_VL53L1X_VL53L1_TYPES_H_ +#define ZEPHYR_DRIVERS_SENSOR_VL53L1X_VL53L1_TYPES_H_ + + +/* Zephyr provides stdint.h and stddef.h, so this is enough to include it. + * If it was not the case, we would defined here all signed and unsigned + * basic types... + */ +#include +#include + +#ifndef NULL +#error "Error NULL definition should be done. Please add required include " +#endif + +/** use where fractional values are expected + * + * Given a floating point value f it's .16 bit point is (int)(f*(1<<16)) + */ +typedef uint32_t FixPoint1616_t; + +#endif /* ZEPHYR_DRIVERS_SENSOR_VL53L1X_VL53L1_TYPES_H_ */ diff --git a/dts/bindings/sensor/st,vl53l1x.yaml b/dts/bindings/sensor/st,vl53l1x.yaml new file mode 100644 index 0000000000000..d5df6706a84c6 --- /dev/null +++ b/dts/bindings/sensor/st,vl53l1x.yaml @@ -0,0 +1,25 @@ +# Copyright (c) 2023 Prosaris Solutions Inc. +# SPDX-License-Identifier: Apache-2.0 + +description: STMicroelectronics VL53L1X Time of Flight sensor + +compatible: "st,vl53l1x" + +include: [sensor-device.yaml, i2c-device.yaml] + +properties: + xshut-gpios: + type: phandle-array + description: | + Driving the XSHUT pin low puts the VL53L1X into hardware + standby (if VDD is present) or complete power off (if + VDD is not present). Additionally, if XSHUT is connected + directly to VDD, the sensor will go into boot mode on a + transition from LOW to HIGH. + + int-gpios: + type: phandle-array + description: | + An interrupt is raised when a distance measurement is ready. + GPIO1 is the interrupt pin on the VL53L1X (active low). This + can be disabled if the user prefers to use polling instead. diff --git a/tests/drivers/build_all/sensor/i2c.dtsi b/tests/drivers/build_all/sensor/i2c.dtsi index 0bddfb4938f9f..5944d1b0faacf 100644 --- a/tests/drivers/build_all/sensor/i2c.dtsi +++ b/tests/drivers/build_all/sensor/i2c.dtsi @@ -664,3 +664,10 @@ test_i2c_wsen_tids: wsen_tids@67 { int-gpios = <&test_gpio 0 0>; odr = <25>; }; + +test_i2c_vl53l1x: vl53l1x@68 { + compatible = "st,vl53l1x"; + reg = <0x68>; + int-gpios = <&test_gpio 0 0>; + xshut-gpios = <&test_gpio 0 0>; +};