Browse Source

drivers/sensor: lis2dux12: add lis2duxs12 support

The LIS2DUXS12 is a smart, digital, 3-axis linear accelerometer whose
MEMS and ASIC have been expressly designed to combine the lowest current
consumption possible with features such as always-on antialiasing
filtering, a finite state machine (FSM) and machine learning core (MLC)
with adaptive self-configuration (ASC), and an analog hub / Qvar sensing
channel.

(https://www.st.com/en/mems-and-sensors/lis2duxs12.html)

Signed-off-by: Armando Visconti <armando.visconti@st.com>
pull/83428/head
Armando Visconti 9 months ago committed by Benjamin Cabé
parent
commit
f9eceaebf9
  1. 1
      drivers/sensor/st/lis2dux12/CMakeLists.txt
  2. 11
      drivers/sensor/st/lis2dux12/Kconfig
  3. 8
      drivers/sensor/st/lis2dux12/lis2dux12.c
  4. 16
      drivers/sensor/st/lis2dux12/lis2dux12.h
  5. 6
      drivers/sensor/st/lis2dux12/lis2dux12_api.h
  6. 237
      drivers/sensor/st/lis2dux12/lis2duxs12_api.c
  7. 24
      drivers/sensor/st/lis2dux12/lis2duxs12_api.h
  8. 17
      dts/bindings/sensor/st,lis2duxs12-common.yaml
  9. 8
      dts/bindings/sensor/st,lis2duxs12-i2c.yaml
  10. 9
      dts/bindings/sensor/st,lis2duxs12-spi.yaml
  11. 3
      modules/hal_st/Kconfig
  12. 11
      tests/drivers/build_all/sensor/i2c.dtsi

1
drivers/sensor/st/lis2dux12/CMakeLists.txt

@ -5,5 +5,6 @@ zephyr_library()
zephyr_library_sources(lis2dux12.c) zephyr_library_sources(lis2dux12.c)
zephyr_library_sources_ifdef(CONFIG_LIS2DUX12_TRIGGER lis2dux12_trigger.c) zephyr_library_sources_ifdef(CONFIG_LIS2DUX12_TRIGGER lis2dux12_trigger.c)
zephyr_library_sources_ifdef(CONFIG_DT_HAS_ST_LIS2DUX12_ENABLED lis2dux12_api.c ) zephyr_library_sources_ifdef(CONFIG_DT_HAS_ST_LIS2DUX12_ENABLED lis2dux12_api.c )
zephyr_library_sources_ifdef(CONFIG_DT_HAS_ST_LIS2DUXS12_ENABLED lis2duxs12_api.c )
zephyr_library_include_directories(../stmemsc) zephyr_library_include_directories(../stmemsc)

11
drivers/sensor/st/lis2dux12/Kconfig

@ -6,12 +6,15 @@
menuconfig LIS2DUX12 menuconfig LIS2DUX12
bool "LIS2DUX12 I2C/SPI accelerometer sensor driver" bool "LIS2DUX12 I2C/SPI accelerometer sensor driver"
default y default y
depends on DT_HAS_ST_LIS2DUX12_ENABLED depends on DT_HAS_ST_LIS2DUX12_ENABLED || DT_HAS_ST_LIS2DUXS12_ENABLED
depends on ZEPHYR_HAL_ST_MODULE depends on ZEPHYR_HAL_ST_MODULE
select I2C if $(dt_compat_on_bus,$(DT_COMPAT_ST_LIS2DUX12),i2c) select I2C if $(dt_compat_on_bus,$(DT_COMPAT_ST_LIS2DUX12),i2c) || \
select SPI if $(dt_compat_on_bus,$(DT_COMPAT_ST_LIS2DUX12),spi) $(dt_compat_on_bus,$(DT_COMPAT_ST_LIS2DUXS12),i2c)
select SPI if $(dt_compat_on_bus,$(DT_COMPAT_ST_LIS2DUX12),spi) || \
$(dt_compat_on_bus,$(DT_COMPAT_ST_LIS2DUXS12),spi)
select HAS_STMEMSC select HAS_STMEMSC
select USE_STDC_LIS2DUX12 select USE_STDC_LIS2DUX12 if DT_HAS_ST_LIS2DUX12_ENABLED
select USE_STDC_LIS2DUXS12 if DT_HAS_ST_LIS2DUXS12_ENABLED
help help
Enable driver for LIS2DUX12 accelerometer sensor driver Enable driver for LIS2DUX12 accelerometer sensor driver

8
drivers/sensor/st/lis2dux12/lis2dux12.c

@ -23,6 +23,10 @@
#include "lis2dux12_api.h" #include "lis2dux12_api.h"
#endif #endif
#if DT_HAS_COMPAT_STATUS_OKAY(st_lis2duxs12)
#include "lis2duxs12_api.h"
#endif
LOG_MODULE_REGISTER(LIS2DUX12, CONFIG_SENSOR_LOG_LEVEL); LOG_MODULE_REGISTER(LIS2DUX12, CONFIG_SENSOR_LOG_LEVEL);
#define FOREACH_ODR_ENUM(ODR_VAL) \ #define FOREACH_ODR_ENUM(ODR_VAL) \
@ -305,3 +309,7 @@ static DEVICE_API(sensor, lis2dux12_driver_api) = {
#define DT_DRV_COMPAT st_lis2dux12 #define DT_DRV_COMPAT st_lis2dux12
DT_INST_FOREACH_STATUS_OKAY_VARGS(LIS2DUX12_DEFINE, DT_DRV_COMPAT) DT_INST_FOREACH_STATUS_OKAY_VARGS(LIS2DUX12_DEFINE, DT_DRV_COMPAT)
#undef DT_DRV_COMPAT #undef DT_DRV_COMPAT
#define DT_DRV_COMPAT st_lis2duxs12
DT_INST_FOREACH_STATUS_OKAY_VARGS(LIS2DUX12_DEFINE, DT_DRV_COMPAT)
#undef DT_DRV_COMPAT

16
drivers/sensor/st/lis2dux12/lis2dux12.h

@ -20,11 +20,17 @@
#include "lis2dux12_reg.h" #include "lis2dux12_reg.h"
#endif #endif
#if DT_HAS_COMPAT_ON_BUS_STATUS_OKAY(st_lis2dux12, spi) #if DT_HAS_COMPAT_STATUS_OKAY(st_lis2duxs12)
#include "lis2duxs12_reg.h"
#endif
#if DT_HAS_COMPAT_ON_BUS_STATUS_OKAY(st_lis2dux12, spi) || \
DT_HAS_COMPAT_ON_BUS_STATUS_OKAY(st_lis2duxs12, spi)
#include <zephyr/drivers/spi.h> #include <zephyr/drivers/spi.h>
#endif #endif
#if DT_HAS_COMPAT_ON_BUS_STATUS_OKAY(st_lis2dux12, i2c) #if DT_HAS_COMPAT_ON_BUS_STATUS_OKAY(st_lis2dux12, i2c) || \
DT_HAS_COMPAT_ON_BUS_STATUS_OKAY(st_lis2duxs12, i2c)
#include <zephyr/drivers/i2c.h> #include <zephyr/drivers/i2c.h>
#endif #endif
@ -55,10 +61,12 @@ struct lis2dux12_chip_api {
struct lis2dux12_config { struct lis2dux12_config {
stmdev_ctx_t ctx; stmdev_ctx_t ctx;
union { union {
#if DT_HAS_COMPAT_ON_BUS_STATUS_OKAY(st_lis2dux12, i2c) #if DT_HAS_COMPAT_ON_BUS_STATUS_OKAY(st_lis2dux12, i2c) || \
DT_HAS_COMPAT_ON_BUS_STATUS_OKAY(st_lis2duxs12, i2c)
const struct i2c_dt_spec i2c; const struct i2c_dt_spec i2c;
#endif #endif
#if DT_HAS_COMPAT_ON_BUS_STATUS_OKAY(st_lis2dux12, spi) #if DT_HAS_COMPAT_ON_BUS_STATUS_OKAY(st_lis2dux12, spi) || \
DT_HAS_COMPAT_ON_BUS_STATUS_OKAY(st_lis2duxs12, spi)
const struct spi_dt_spec spi; const struct spi_dt_spec spi;
#endif #endif
} stmemsc_cfg; } stmemsc_cfg;

6
drivers/sensor/st/lis2dux12/lis2dux12_api.h

@ -14,11 +14,11 @@
#include <zephyr/drivers/sensor.h> #include <zephyr/drivers/sensor.h>
#ifndef ZEPHYR_DRIVERS_SENSOR_LIS2DUX12_ST_LIS2DUX12_H_ #ifndef ZEPHYR_DRIVERS_SENSOR_LIS2DUX12_LIS2DUX12_API_H_
#define ZEPHYR_DRIVERS_SENSOR_LIS2DUX12_ST_LIS2DUX12_H_ #define ZEPHYR_DRIVERS_SENSOR_LIS2DUX12_LIS2DUX12_API_H_
extern const struct lis2dux12_chip_api st_lis2dux12_chip_api; extern const struct lis2dux12_chip_api st_lis2dux12_chip_api;
int st_lis2dux12_init(const struct device *dev); int st_lis2dux12_init(const struct device *dev);
#endif /* ZEPHYR_DRIVERS_SENSOR_LIS2DUX12_ST_LIS2DUX12_H_ */ #endif /* ZEPHYR_DRIVERS_SENSOR_LIS2DUX12_LIS2DUX12_API_H_ */

237
drivers/sensor/st/lis2dux12/lis2duxs12_api.c

@ -0,0 +1,237 @@
/* ST Microelectronics LIS2DUXS12 smart accelerometer APIs
*
* Copyright (c) 2024 STMicroelectronics
* Copyright (c) 2023 PHYTEC Messtechnik GmbH
*
* SPDX-License-Identifier: Apache-2.0
*/
#include "lis2dux12.h"
#include "lis2duxs12_api.h"
#include <zephyr/logging/log.h>
LOG_MODULE_DECLARE(LIS2DUX12, CONFIG_SENSOR_LOG_LEVEL);
static int32_t st_lis2duxs12_set_odr_raw(const struct device *dev, uint8_t odr)
{
struct lis2dux12_data *data = dev->data;
const struct lis2dux12_config *cfg = dev->config;
stmdev_ctx_t *ctx = (stmdev_ctx_t *)&cfg->ctx;
lis2duxs12_md_t mode = {.odr = odr, .fs = data->range};
data->odr = odr;
return lis2duxs12_mode_set(ctx, &mode);
}
static int32_t st_lis2duxs12_set_range(const struct device *dev, uint8_t range)
{
int err;
struct lis2dux12_data *data = dev->data;
const struct lis2dux12_config *cfg = dev->config;
stmdev_ctx_t *ctx = (stmdev_ctx_t *)&cfg->ctx;
lis2duxs12_md_t val = { .odr = data->odr, .fs = range };
err = lis2duxs12_mode_set(ctx, &val);
if (err) {
return err;
}
switch (range) {
case LIS2DUX12_DT_FS_2G:
data->gain = lis2duxs12_from_fs2g_to_mg(1);
break;
case LIS2DUX12_DT_FS_4G:
data->gain = lis2duxs12_from_fs4g_to_mg(1);
break;
case LIS2DUX12_DT_FS_8G:
data->gain = lis2duxs12_from_fs8g_to_mg(1);
break;
case LIS2DUX12_DT_FS_16G:
data->gain = lis2duxs12_from_fs16g_to_mg(1);
break;
default:
LOG_ERR("range %d not supported.", range);
return -EINVAL;
}
data->range = range;
return 0;
}
static int32_t st_lis2duxs12_sample_fetch_accel(const struct device *dev)
{
struct lis2dux12_data *data = dev->data;
const struct lis2dux12_config *cfg = dev->config;
stmdev_ctx_t *ctx = (stmdev_ctx_t *)&cfg->ctx;
/* fetch raw data sample */
lis2duxs12_md_t mode = {.fs = data->range};
lis2duxs12_xl_data_t xzy_data = {0};
if (lis2duxs12_xl_data_get(ctx, &mode, &xzy_data) < 0) {
LOG_ERR("Failed to fetch raw data sample");
return -EIO;
}
data->sample_x = xzy_data.raw[0];
data->sample_y = xzy_data.raw[1];
data->sample_z = xzy_data.raw[2];
return 0;
}
#ifdef CONFIG_LIS2DUX12_ENABLE_TEMP
static int32_t st_lis2duxs12_sample_fetch_temp(const struct device *dev)
{
struct lis2dux12_data *data = dev->data;
const struct lis2dux12_config *cfg = dev->config;
stmdev_ctx_t *ctx = (stmdev_ctx_t *)&cfg->ctx;
/* fetch raw data sample */
lis2duxs12_outt_data_t temp_data = {0};
if (lis2duxs12_outt_data_get(ctx, &temp_data) < 0) {
LOG_ERR("Failed to fetch raw temperature data sample");
return -EIO;
}
data->sample_temp = temp_data.heat.deg_c;
return 0;
}
#endif
#ifdef CONFIG_LIS2DUX12_TRIGGER
static void st_lis2duxs12_handle_interrupt(const struct device *dev)
{
struct lis2dux12_data *lis2duxs12 = dev->data;
const struct lis2dux12_config *cfg = dev->config;
stmdev_ctx_t *ctx = (stmdev_ctx_t *)&cfg->ctx;
lis2duxs12_all_sources_t sources;
int ret;
lis2duxs12_all_sources_get(ctx, &sources);
if (sources.drdy == 0) {
goto exit; /* spurious interrupt */
}
if (lis2duxs12->data_ready_handler != NULL) {
lis2duxs12->data_ready_handler(dev, lis2duxs12->data_ready_trigger);
}
exit:
ret = gpio_pin_interrupt_configure_dt(lis2duxs12->drdy_gpio, GPIO_INT_EDGE_TO_ACTIVE);
if (ret < 0) {
LOG_ERR("%s: Not able to configure pin_int", dev->name);
}
}
static int32_t st_lis2duxs12_init_interrupt(const struct device *dev)
{
const struct lis2dux12_config *cfg = dev->config;
stmdev_ctx_t *ctx = (stmdev_ctx_t *)&cfg->ctx;
lis2duxs12_pin_int_route_t route;
int err;
/* Enable pulsed mode */
err = lis2duxs12_data_ready_mode_set(ctx, LIS2DUXS12_DRDY_PULSED);
if (err < 0) {
return err;
}
/* route data-ready interrupt on int1 */
err = lis2duxs12_pin_int1_route_get(ctx, &route);
if (err < 0) {
return err;
}
route.drdy = 1;
err = lis2duxs12_pin_int1_route_set(ctx, &route);
if (err < 0) {
return err;
}
return 0;
}
#endif
const struct lis2dux12_chip_api st_lis2duxs12_chip_api = {
.set_odr_raw = st_lis2duxs12_set_odr_raw,
.set_range = st_lis2duxs12_set_range,
.sample_fetch_accel = st_lis2duxs12_sample_fetch_accel,
#ifdef CONFIG_LIS2DUX12_ENABLE_TEMP
.sample_fetch_temp = st_lis2duxs12_sample_fetch_temp,
#endif
#ifdef CONFIG_LIS2DUX12_TRIGGER
.handle_interrupt = st_lis2duxs12_handle_interrupt,
.init_interrupt = st_lis2duxs12_init_interrupt,
#endif
};
int st_lis2duxs12_init(const struct device *dev)
{
const struct lis2dux12_config *const cfg = dev->config;
stmdev_ctx_t *ctx = (stmdev_ctx_t *)&cfg->ctx;
uint8_t chip_id;
int ret;
lis2duxs12_exit_deep_power_down(ctx);
k_busy_wait(25000);
/* check chip ID */
ret = lis2duxs12_device_id_get(ctx, &chip_id);
if (ret < 0) {
LOG_ERR("%s: Not able to read dev id", dev->name);
return ret;
}
if (chip_id != LIS2DUXS12_ID) {
LOG_ERR("%s: Invalid chip ID 0x%02x", dev->name, chip_id);
return -EINVAL;
}
/* reset device */
ret = lis2duxs12_init_set(ctx, LIS2DUXS12_RESET);
if (ret < 0) {
return ret;
}
k_busy_wait(100);
LOG_INF("%s: chip id 0x%x", dev->name, chip_id);
/* Set bdu and if_inc recommended for driver usage */
lis2duxs12_init_set(ctx, LIS2DUXS12_SENSOR_ONLY_ON);
lis2duxs12_timestamp_set(ctx, PROPERTY_ENABLE);
#ifdef CONFIG_LIS2DUX12_TRIGGER
if (cfg->trig_enabled) {
ret = lis2dux12_trigger_init(dev);
if (ret < 0) {
LOG_ERR("%s: Failed to initialize triggers", dev->name);
return ret;
}
}
#endif
/* set sensor default pm and odr */
LOG_DBG("%s: pm: %d, odr: %d", dev->name, cfg->pm, cfg->odr);
ret = st_lis2duxs12_set_odr_raw(dev, cfg->odr);
if (ret < 0) {
LOG_ERR("%s: odr init error (12.5 Hz)", dev->name);
return ret;
}
/* set sensor default scale (used to convert sample values) */
LOG_DBG("%s: range is %d", dev->name, cfg->range);
ret = st_lis2duxs12_set_range(dev, cfg->range);
if (ret < 0) {
LOG_ERR("%s: range init error %d", dev->name, cfg->range);
return ret;
}
return 0;
}

24
drivers/sensor/st/lis2dux12/lis2duxs12_api.h

@ -0,0 +1,24 @@
/* ST Microelectronics LIS2DUXS12 smart accelerometer APIs
*
* Copyright (c) 2024 STMicroelectronics
* Copyright (c) 2023 PHYTEC Messtechnik GmbH
*
* SPDX-License-Identifier: Apache-2.0
*/
#include <stdint.h>
#include <stmemsc.h>
#include "lis2duxs12_reg.h"
#include <zephyr/dt-bindings/sensor/lis2dux12.h>
#include <zephyr/drivers/sensor.h>
#ifndef ZEPHYR_DRIVERS_SENSOR_LIS2DUXS12_LIS2DUXS12_API_H_
#define ZEPHYR_DRIVERS_SENSOR_LIS2DUXS12_LIS2DUXS12_API_H_
extern const struct lis2dux12_chip_api st_lis2duxs12_chip_api;
int st_lis2duxs12_init(const struct device *dev);
#endif /* ZEPHYR_DRIVERS_SENSOR_LIS2DUXS12_LIS2DUXS12_API_H_ */

17
dts/bindings/sensor/st,lis2duxs12-common.yaml

@ -0,0 +1,17 @@
# Copyright (c) 2024 STMicroelectronics
# SPDX-License-Identifier: Apache-2.0
description: |
When setting the odr, power-mode, and range properties in a .dts or .dtsi file you may include
st_lis2dux12.h and use the macros defined there.
Example:
#include <zephyr/dt-bindings/sensor/st_lis2dux12.h>
lis2duxs12: lis2duxs12@0 {
...
power-mode = <LIS2DUX12_OPER_MODE_LOW_POWER>;
odr = <LIS2DUX12_DT_ODR_12Hz5>;
range = <LIS2DUX12_DT_FS_16G>;
};
# LIS2DUXS12 is a superset of LIS2DUX12
include: st,lis2dux12-common.yaml

8
dts/bindings/sensor/st,lis2duxs12-i2c.yaml

@ -0,0 +1,8 @@
# Copyright (c) 2024 STMicroelectronics
# SPDX-License-Identifier: Apache-2.0
description: STMicroelectronics LIS2DUXS12 3-axis accelerometer
compatible: "st,lis2duxs12"
include: ["i2c-device.yaml", "st,lis2duxs12-common.yaml"]

9
dts/bindings/sensor/st,lis2duxs12-spi.yaml

@ -0,0 +1,9 @@
# Copyright (c) 2024 STMicroelectronics
# SPDX-License-Identifier: Apache-2.0
description: |
STMicroelectronics LIS2DUXS12 3-axis accelerometer accessed through SPI bus
compatible: "st,lis2duxs12"
include: ["spi-device.yaml", "st,lis2duxs12-common.yaml"]

3
modules/hal_st/Kconfig

@ -96,6 +96,9 @@ config USE_STDC_LIS2DU12
config USE_STDC_LIS2DUX12 config USE_STDC_LIS2DUX12
bool bool
config USE_STDC_LIS2DUXS12
bool
config USE_STDC_LIS2DW12 config USE_STDC_LIS2DW12
bool bool

11
tests/drivers/build_all/sensor/i2c.dtsi

@ -1190,3 +1190,14 @@ test_i2c_hs400x: hs400x@a6 {
compatible = "renesas,hs400x"; compatible = "renesas,hs400x";
reg = <0xa6>; reg = <0xa6>;
}; };
test_i2c_lis2duxs12: lis2duxs12@a7 {
compatible = "st,lis2duxs12";
reg = <0xa7>;
int1-gpios = <&test_gpio 0 0>;
int2-gpios = <&test_gpio 0 0>;
range = <LIS2DUX12_DT_FS_16G>;
odr = <LIS2DUX12_DT_ODR_100Hz>;
power-mode = <LIS2DUX12_OPER_MODE_HIGH_FREQUENCY>;
status = "okay";
};

Loading…
Cancel
Save