drivers: add iis328dq stmemsc driver
Based on the iis2dlpc driver, with some significant differences in interrupt handling. Signed-off-by: Armin Brauns <armin.brauns@embedded-solutions.at>
This commit is contained in:
parent
808d897ca8
commit
f4c596ae28
13 changed files with 1041 additions and 7 deletions
|
@ -66,6 +66,7 @@ add_subdirectory_ifdef(CONFIG_IIS2DLPC iis2dlpc)
|
|||
add_subdirectory_ifdef(CONFIG_IIS2ICLX iis2iclx)
|
||||
add_subdirectory_ifdef(CONFIG_IIS2MDC iis2mdc)
|
||||
add_subdirectory_ifdef(CONFIG_IIS3DHHC iis3dhhc)
|
||||
add_subdirectory_ifdef(CONFIG_IIS328DQ iis328dq)
|
||||
add_subdirectory_ifdef(CONFIG_INA219 ina219)
|
||||
add_subdirectory_ifdef(CONFIG_INA23X ina23x)
|
||||
add_subdirectory_ifdef(CONFIG_INA3221 ina3221)
|
||||
|
|
|
@ -145,6 +145,7 @@ source "drivers/sensor/iis2dlpc/Kconfig"
|
|||
source "drivers/sensor/iis2iclx/Kconfig"
|
||||
source "drivers/sensor/iis2mdc/Kconfig"
|
||||
source "drivers/sensor/iis3dhhc/Kconfig"
|
||||
source "drivers/sensor/iis328dq/Kconfig"
|
||||
source "drivers/sensor/ina219/Kconfig"
|
||||
source "drivers/sensor/ina23x/Kconfig"
|
||||
source "drivers/sensor/ina3221/Kconfig"
|
||||
|
|
13
drivers/sensor/iis328dq/CMakeLists.txt
Normal file
13
drivers/sensor/iis328dq/CMakeLists.txt
Normal file
|
@ -0,0 +1,13 @@
|
|||
# ST Microelectronics IIS328DQ 3-axis accelerometer driver
|
||||
#
|
||||
# Copyright (c) 2020 STMicroelectronics
|
||||
# Copyright (c) 2024 SILA Embedded Solutions GmbH
|
||||
#
|
||||
# SPDX-License-Identifier: Apache-2.0
|
||||
#
|
||||
zephyr_library()
|
||||
|
||||
zephyr_library_sources(iis328dq.c)
|
||||
zephyr_library_sources_ifdef(CONFIG_IIS328DQ_TRIGGER iis328dq_trigger.c)
|
||||
|
||||
zephyr_library_include_directories(../stmemsc)
|
35
drivers/sensor/iis328dq/Kconfig
Normal file
35
drivers/sensor/iis328dq/Kconfig
Normal file
|
@ -0,0 +1,35 @@
|
|||
# ST Microelectronics IIS328DQ 3-axis accelerometer driver
|
||||
|
||||
# Copyright (c) 2020 STMicroelectronics
|
||||
# Copyright (c) 2024 SILA Embedded Solutions GmbH
|
||||
# SPDX-License-Identifier: Apache-2.0
|
||||
|
||||
menuconfig IIS328DQ
|
||||
bool "IIS328DQ I2C/SPI accelerometer sensor driver"
|
||||
default y
|
||||
depends on DT_HAS_ST_IIS328DQ_ENABLED
|
||||
depends on ZEPHYR_HAL_ST_MODULE
|
||||
select I2C if $(dt_compat_on_bus,$(DT_COMPAT_ST_IIS328DQ),i2c)
|
||||
select SPI if $(dt_compat_on_bus,$(DT_COMPAT_ST_IIS328DQ),spi)
|
||||
select HAS_STMEMSC
|
||||
select USE_STDC_IIS328DQ
|
||||
help
|
||||
Enable driver for IIS328DQ accelerometer sensor driver
|
||||
|
||||
if IIS328DQ
|
||||
|
||||
module = IIS328DQ
|
||||
thread_priority = 10
|
||||
thread_stack_size = 1024
|
||||
source "drivers/sensor/Kconfig.trigger_template"
|
||||
|
||||
if IIS328DQ_TRIGGER
|
||||
|
||||
config IIS328DQ_THRESHOLD
|
||||
bool "Threshold detection"
|
||||
help
|
||||
Enable threshold interrupts
|
||||
|
||||
endif # IIS328DQ_TRIGGER
|
||||
|
||||
endif # IIS328DQ
|
460
drivers/sensor/iis328dq/iis328dq.c
Normal file
460
drivers/sensor/iis328dq/iis328dq.c
Normal file
|
@ -0,0 +1,460 @@
|
|||
/* ST Microelectronics IIS328DQ 3-axis accelerometer driver
|
||||
*
|
||||
* Copyright (c) 2020 STMicroelectronics
|
||||
* Copyright (c) 2024 SILA Embedded Solutions GmbH
|
||||
*
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
*
|
||||
* Datasheet:
|
||||
* https://www.st.com/resource/en/datasheet/iis328dq.pdf
|
||||
*/
|
||||
|
||||
#define DT_DRV_COMPAT st_iis328dq
|
||||
|
||||
#include <string.h>
|
||||
#include <zephyr/init.h>
|
||||
#include <zephyr/sys/__assert.h>
|
||||
#include <zephyr/sys/byteorder.h>
|
||||
#include <zephyr/logging/log.h>
|
||||
#include <zephyr/drivers/sensor.h>
|
||||
|
||||
#if DT_ANY_INST_ON_BUS_STATUS_OKAY(spi)
|
||||
#include <zephyr/drivers/spi.h>
|
||||
#elif DT_ANY_INST_ON_BUS_STATUS_OKAY(i2c)
|
||||
#include <zephyr/drivers/i2c.h>
|
||||
#endif
|
||||
|
||||
#include "iis328dq.h"
|
||||
|
||||
LOG_MODULE_REGISTER(IIS328DQ, CONFIG_SENSOR_LOG_LEVEL);
|
||||
|
||||
/**
|
||||
* iis328dq_set_odr - set new Full Scale (in ±g)
|
||||
*/
|
||||
static int iis328dq_set_range(const struct device *dev, uint8_t fs)
|
||||
{
|
||||
int err;
|
||||
struct iis328dq_data *iis328dq = dev->data;
|
||||
const struct iis328dq_config *cfg = dev->config;
|
||||
stmdev_ctx_t *ctx = (stmdev_ctx_t *)&cfg->ctx;
|
||||
iis328dq_fs_t fs_reg;
|
||||
uint8_t gain;
|
||||
|
||||
if (fs <= 2) {
|
||||
fs_reg = IIS328DQ_2g;
|
||||
gain = 1;
|
||||
} else if (fs <= 4) {
|
||||
fs_reg = IIS328DQ_4g;
|
||||
gain = 2;
|
||||
} else if (fs <= 8) {
|
||||
fs_reg = IIS328DQ_8g;
|
||||
gain = 4;
|
||||
} else {
|
||||
LOG_ERR("FS too high");
|
||||
return -ENOTSUP;
|
||||
}
|
||||
err = iis328dq_full_scale_set(ctx, fs_reg);
|
||||
|
||||
if (!err) {
|
||||
iis328dq->gain = gain;
|
||||
}
|
||||
|
||||
return err;
|
||||
}
|
||||
|
||||
/**
|
||||
* iis328dq_set_odr - set new Output Data Rate/sampling frequency (in Hz)
|
||||
*/
|
||||
static int iis328dq_set_odr(const struct device *dev, uint16_t odr)
|
||||
{
|
||||
const struct iis328dq_config *cfg = dev->config;
|
||||
stmdev_ctx_t *ctx = (stmdev_ctx_t *)&cfg->ctx;
|
||||
|
||||
iis328dq_dr_t odr_reg;
|
||||
|
||||
if (odr == 0U) {
|
||||
odr_reg = IIS328DQ_ODR_OFF;
|
||||
} else if (odr <= 1) {
|
||||
odr_reg = IIS328DQ_ODR_1Hz;
|
||||
} else if (odr <= 2) {
|
||||
/* not sure what "5Hz2" is about, datasheet says PM=0b100 is 2Hz
|
||||
* https://github.com/STMicroelectronics/STMems_Standard_C_drivers/issues/162
|
||||
*/
|
||||
odr_reg = IIS328DQ_ODR_5Hz2;
|
||||
} else if (odr <= 5) {
|
||||
odr_reg = IIS328DQ_ODR_5Hz;
|
||||
} else if (odr <= 10) {
|
||||
odr_reg = IIS328DQ_ODR_10Hz;
|
||||
} else if (odr <= 50) {
|
||||
odr_reg = IIS328DQ_ODR_50Hz;
|
||||
} else if (odr <= 100) {
|
||||
odr_reg = IIS328DQ_ODR_100Hz;
|
||||
} else if (odr <= 400) {
|
||||
odr_reg = IIS328DQ_ODR_400Hz;
|
||||
} else if (odr <= 1000) {
|
||||
odr_reg = IIS328DQ_ODR_1kHz;
|
||||
} else {
|
||||
LOG_ERR("ODR too high");
|
||||
return -ENOTSUP;
|
||||
}
|
||||
|
||||
if (iis328dq_data_rate_set(ctx, odr_reg) != 0) {
|
||||
LOG_ERR("Failed to set ODR");
|
||||
return -EIO;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static inline void iis328dq_convert(struct sensor_value *val, int raw_val, uint8_t gain)
|
||||
{
|
||||
int64_t dval;
|
||||
|
||||
/* Gain is in mg/LSB */
|
||||
/* Convert to μm/s^2 */
|
||||
dval = ((int64_t)raw_val * gain * SENSOR_G) / 1000LL;
|
||||
val->val1 = dval / 1000000LL;
|
||||
val->val2 = dval % 1000000LL;
|
||||
}
|
||||
|
||||
static inline void iis328dq_channel_get_acc(const struct device *dev, enum sensor_channel chan,
|
||||
struct sensor_value *val)
|
||||
{
|
||||
int i;
|
||||
uint8_t ofs_start, ofs_stop;
|
||||
struct iis328dq_data *iis328dq = dev->data;
|
||||
struct sensor_value *pval = val;
|
||||
|
||||
switch (chan) {
|
||||
case SENSOR_CHAN_ACCEL_X:
|
||||
ofs_start = ofs_stop = 0U;
|
||||
break;
|
||||
case SENSOR_CHAN_ACCEL_Y:
|
||||
ofs_start = ofs_stop = 1U;
|
||||
break;
|
||||
case SENSOR_CHAN_ACCEL_Z:
|
||||
ofs_start = ofs_stop = 2U;
|
||||
break;
|
||||
default:
|
||||
ofs_start = 0U;
|
||||
ofs_stop = 2U;
|
||||
break;
|
||||
}
|
||||
|
||||
for (i = ofs_start; i <= ofs_stop; i++) {
|
||||
iis328dq_convert(pval++, iis328dq->acc[i], iis328dq->gain);
|
||||
}
|
||||
}
|
||||
|
||||
static int iis328dq_channel_get(const struct device *dev, enum sensor_channel chan,
|
||||
struct sensor_value *val)
|
||||
{
|
||||
switch (chan) {
|
||||
case SENSOR_CHAN_ACCEL_X:
|
||||
case SENSOR_CHAN_ACCEL_Y:
|
||||
case SENSOR_CHAN_ACCEL_Z:
|
||||
case SENSOR_CHAN_ACCEL_XYZ:
|
||||
iis328dq_channel_get_acc(dev, chan, val);
|
||||
return 0;
|
||||
default:
|
||||
LOG_DBG("Channel not supported");
|
||||
break;
|
||||
}
|
||||
|
||||
return -ENOTSUP;
|
||||
}
|
||||
|
||||
#ifdef CONFIG_IIS328DQ_THRESHOLD
|
||||
static int iis328dq_set_threshold(const struct device *dev, bool is_lower,
|
||||
const struct sensor_value *val)
|
||||
{
|
||||
int err;
|
||||
const struct iis328dq_config *cfg = dev->config;
|
||||
struct iis328dq_data *iis328dq = dev->data;
|
||||
stmdev_ctx_t *ctx = (stmdev_ctx_t *)&cfg->ctx;
|
||||
|
||||
if (val->val1 < 0 || val->val2 < 0) {
|
||||
/* thresholds are absolute */
|
||||
return -EINVAL;
|
||||
}
|
||||
int64_t micro_ms2 = (val->val1 * INT64_C(1000000)) + val->val2;
|
||||
/* factor guessed from similar-looking LIS2DH12 datasheet */
|
||||
uint8_t mg_per_digit = iis328dq->gain * 16;
|
||||
|
||||
int16_t val_raw = (micro_ms2 * 1000LL) / SENSOR_G / mg_per_digit;
|
||||
|
||||
if (is_lower) {
|
||||
/* internal INT1 handles lower threshold */
|
||||
err = iis328dq_int1_treshold_set(ctx, val_raw);
|
||||
if (err) {
|
||||
LOG_ERR("Could not set INT1_THS to 0x%02X, error %d", val_raw, err);
|
||||
return err;
|
||||
}
|
||||
} else {
|
||||
/* internal INT2 handles lower threshold */
|
||||
err = iis328dq_int2_treshold_set(ctx, val_raw);
|
||||
if (err) {
|
||||
LOG_ERR("Could not set INT2_THS to 0x%02X, error %d", val_raw, err);
|
||||
return err;
|
||||
}
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int iis328dq_set_duration(const struct device *dev, uint16_t dur)
|
||||
{
|
||||
int err;
|
||||
const struct iis328dq_config *cfg = dev->config;
|
||||
stmdev_ctx_t *ctx = (stmdev_ctx_t *)&cfg->ctx;
|
||||
|
||||
if (dur > 0x7F) {
|
||||
LOG_WRN("Duration value %u too large", dur);
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
err = iis328dq_int1_dur_set(ctx, dur);
|
||||
if (err) {
|
||||
LOG_ERR("Could not set INT1_DUR to 0x%02X, error %d", dur, err);
|
||||
return err;
|
||||
}
|
||||
err = iis328dq_int2_dur_set(ctx, dur);
|
||||
if (err) {
|
||||
LOG_ERR("Could not set INT2_DUR to 0x%02X, error %d", dur, err);
|
||||
return err;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
#endif /* CONFIG_IIS328DQ_THRESHOLD */
|
||||
#define IIS328DQ_ATTR_DURATION SENSOR_ATTR_PRIV_START
|
||||
|
||||
static int iis328dq_dev_config(const struct device *dev, enum sensor_channel chan,
|
||||
enum sensor_attribute attr, const struct sensor_value *val)
|
||||
{
|
||||
switch (attr) {
|
||||
case SENSOR_ATTR_FULL_SCALE:
|
||||
return iis328dq_set_range(dev, sensor_ms2_to_g(val));
|
||||
case SENSOR_ATTR_SAMPLING_FREQUENCY:
|
||||
return iis328dq_set_odr(dev, val->val1);
|
||||
#ifdef CONFIG_IIS328DQ_THRESHOLD
|
||||
case SENSOR_ATTR_LOWER_THRESH:
|
||||
case SENSOR_ATTR_UPPER_THRESH:
|
||||
if (chan != SENSOR_CHAN_ACCEL_XYZ) {
|
||||
LOG_ERR("Threshold cannot be set per-channel");
|
||||
return -ENOTSUP;
|
||||
}
|
||||
return iis328dq_set_threshold(dev, attr == SENSOR_ATTR_LOWER_THRESH, val);
|
||||
case IIS328DQ_ATTR_DURATION:
|
||||
if (chan != SENSOR_CHAN_ACCEL_XYZ) {
|
||||
LOG_ERR("Duration cannot be set per-channel");
|
||||
return -ENOTSUP;
|
||||
}
|
||||
return iis328dq_set_duration(dev, val->val1);
|
||||
#endif /* CONFIG_IIS328DQ_THRESHOLD */
|
||||
default:
|
||||
LOG_DBG("Acc attribute not supported");
|
||||
break;
|
||||
}
|
||||
|
||||
return -ENOTSUP;
|
||||
}
|
||||
|
||||
static int iis328dq_attr_set(const struct device *dev, enum sensor_channel chan,
|
||||
enum sensor_attribute attr, const struct sensor_value *val)
|
||||
{
|
||||
switch (chan) {
|
||||
case SENSOR_CHAN_ACCEL_X:
|
||||
case SENSOR_CHAN_ACCEL_Y:
|
||||
case SENSOR_CHAN_ACCEL_Z:
|
||||
case SENSOR_CHAN_ACCEL_XYZ:
|
||||
case SENSOR_CHAN_ALL:
|
||||
return iis328dq_dev_config(dev, chan, attr, val);
|
||||
default:
|
||||
LOG_DBG("Attr not supported on %d channel", chan);
|
||||
break;
|
||||
}
|
||||
|
||||
return -ENOTSUP;
|
||||
}
|
||||
|
||||
static int iis328dq_sample_fetch(const struct device *dev, enum sensor_channel chan)
|
||||
{
|
||||
struct iis328dq_data *iis328dq = dev->data;
|
||||
const struct iis328dq_config *cfg = dev->config;
|
||||
stmdev_ctx_t *ctx = (stmdev_ctx_t *)&cfg->ctx;
|
||||
int16_t buf[3];
|
||||
|
||||
/* fetch raw data sample */
|
||||
if (iis328dq_acceleration_raw_get(ctx, buf) < 0) {
|
||||
LOG_DBG("Failed to fetch raw data sample");
|
||||
return -EIO;
|
||||
}
|
||||
|
||||
iis328dq->acc[0] = buf[0] >> 4;
|
||||
iis328dq->acc[1] = buf[1] >> 4;
|
||||
iis328dq->acc[2] = buf[2] >> 4;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static const struct sensor_driver_api iis328dq_driver_api = {
|
||||
.attr_set = iis328dq_attr_set,
|
||||
#if CONFIG_IIS328DQ_TRIGGER
|
||||
.trigger_set = iis328dq_trigger_set,
|
||||
#endif /* CONFIG_IIS328DQ_TRIGGER */
|
||||
.sample_fetch = iis328dq_sample_fetch,
|
||||
.channel_get = iis328dq_channel_get,
|
||||
};
|
||||
|
||||
static int iis328dq_init(const struct device *dev)
|
||||
{
|
||||
struct iis328dq_data *iis328dq = dev->data;
|
||||
const struct iis328dq_config *cfg = dev->config;
|
||||
stmdev_ctx_t *ctx = (stmdev_ctx_t *)&cfg->ctx;
|
||||
uint8_t reg_value;
|
||||
|
||||
iis328dq->dev = dev;
|
||||
|
||||
/* check chip ID */
|
||||
if (iis328dq_device_id_get(ctx, ®_value) < 0) {
|
||||
return -EIO;
|
||||
}
|
||||
|
||||
if (reg_value != IIS328DQ_ID) {
|
||||
LOG_ERR("Invalid chip ID");
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
/* reset device */
|
||||
if (iis328dq_boot_set(ctx, PROPERTY_ENABLE) < 0) {
|
||||
return -EIO;
|
||||
}
|
||||
|
||||
k_sleep(K_MSEC(100));
|
||||
|
||||
if (iis328dq_boot_get(ctx, ®_value) < 0) {
|
||||
return -EIO;
|
||||
}
|
||||
if (reg_value != PROPERTY_DISABLE) {
|
||||
LOG_ERR("BOOT did not deassert");
|
||||
return -EIO;
|
||||
}
|
||||
|
||||
if (iis328dq_block_data_update_set(ctx, PROPERTY_ENABLE) < 0) {
|
||||
return -EIO;
|
||||
}
|
||||
|
||||
/* set default odr to 12.5Hz acc */
|
||||
if (iis328dq_set_odr(dev, 12) < 0) {
|
||||
LOG_ERR("odr init error (12.5 Hz)");
|
||||
return -EIO;
|
||||
}
|
||||
|
||||
if (iis328dq_set_range(dev, cfg->range) < 0) {
|
||||
LOG_ERR("range init error %d", cfg->range);
|
||||
return -EIO;
|
||||
}
|
||||
|
||||
#ifdef CONFIG_IIS328DQ_TRIGGER
|
||||
if (iis328dq_init_interrupt(dev) < 0) {
|
||||
LOG_ERR("Failed to initialize interrupts");
|
||||
return -EIO;
|
||||
}
|
||||
#endif /* CONFIG_IIS328DQ_TRIGGER */
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
/*
|
||||
* Device creation macro, shared by IIS328DQ_DEFINE_SPI() and
|
||||
* IIS328DQ_DEFINE_I2C().
|
||||
*/
|
||||
|
||||
#define IIS328DQ_DEVICE_INIT(inst) \
|
||||
SENSOR_DEVICE_DT_INST_DEFINE(inst, iis328dq_init, NULL, &iis328dq_data_##inst, \
|
||||
&iis328dq_config_##inst, POST_KERNEL, \
|
||||
CONFIG_SENSOR_INIT_PRIORITY, &iis328dq_driver_api);
|
||||
|
||||
#ifdef CONFIG_IIS328DQ_TRIGGER
|
||||
#ifdef CONFIG_IIS328DQ_THRESHOLD
|
||||
#define IIS328DQ_CFG_IRQ_THRESHOLD(inst) \
|
||||
.threshold_pad = DT_INST_PROP_OR(inst, threshold_int_pad, -1),
|
||||
#else
|
||||
#define IIS328DQ_CFG_IRQ_THRESHOLD(inst)
|
||||
#endif /* CONFIG_IIS328DQ_THRESHOLD */
|
||||
|
||||
#define IIS328DQ_CFG_IRQ(inst) \
|
||||
.gpio_int1 = GPIO_DT_SPEC_INST_GET_OR(inst, int1_gpios, {0}), \
|
||||
.gpio_int2 = GPIO_DT_SPEC_INST_GET_OR(inst, int2_gpios, {0}), \
|
||||
.drdy_pad = DT_INST_PROP_OR(inst, drdy_int_pad, -1), IIS328DQ_CFG_IRQ_THRESHOLD(inst)
|
||||
#else
|
||||
#define IIS328DQ_CFG_IRQ(inst)
|
||||
#endif /* CONFIG_IIS328DQ_TRIGGER */
|
||||
|
||||
#define IIS328DQ_CONFIG_COMMON(inst) \
|
||||
.range = DT_INST_PROP(inst, range), \
|
||||
IF_ENABLED(UTIL_OR(DT_INST_NODE_HAS_PROP(inst, int1_gpios), \
|
||||
DT_INST_NODE_HAS_PROP(inst, int2_gpios)), \
|
||||
(IIS328DQ_CFG_IRQ(inst)))
|
||||
|
||||
/*
|
||||
* Instantiation macros used when a device is on a SPI bus.
|
||||
*/
|
||||
|
||||
#define IIS328DQ_SPI_OPERATION \
|
||||
(SPI_WORD_SET(8) | SPI_OP_MODE_MASTER | SPI_MODE_CPOL | SPI_MODE_CPHA)
|
||||
|
||||
#define IIS328DQ_CONFIG_SPI(inst) \
|
||||
{ \
|
||||
STMEMSC_CTX_SPI_INCR(&iis328dq_config_##inst.stmemsc_cfg), \
|
||||
.stmemsc_cfg = \
|
||||
{ \
|
||||
.spi = SPI_DT_SPEC_INST_GET(inst, IIS328DQ_SPI_OPERATION, \
|
||||
0), \
|
||||
}, \
|
||||
IIS328DQ_CONFIG_COMMON(inst) \
|
||||
}
|
||||
|
||||
/*
|
||||
* Instantiation macros used when a device is on an I2C bus.
|
||||
*/
|
||||
|
||||
#define IIS328DQ_CONFIG_I2C(inst) \
|
||||
{ \
|
||||
STMEMSC_CTX_I2C_INCR(&iis328dq_config_##inst.stmemsc_cfg), \
|
||||
.stmemsc_cfg = \
|
||||
{ \
|
||||
.i2c = I2C_DT_SPEC_INST_GET(inst), \
|
||||
}, \
|
||||
IIS328DQ_CONFIG_COMMON(inst) \
|
||||
}
|
||||
|
||||
/*
|
||||
* Main instantiation macro. Use of COND_CODE_1() selects the right
|
||||
* bus-specific macro at preprocessor time.
|
||||
*/
|
||||
|
||||
#define IIS328DQ_DEFINE(inst) \
|
||||
static struct iis328dq_data iis328dq_data_##inst; \
|
||||
static const struct iis328dq_config iis328dq_config_##inst = \
|
||||
COND_CODE_1(DT_INST_ON_BUS(inst, spi), (IIS328DQ_CONFIG_SPI(inst)), \
|
||||
(IIS328DQ_CONFIG_I2C(inst))); \
|
||||
IIS328DQ_DEVICE_INIT(inst) \
|
||||
IF_ENABLED(DT_INST_NODE_HAS_PROP(inst, drdy_int_pad), \
|
||||
(BUILD_ASSERT( \
|
||||
DT_INST_NODE_HAS_PROP( \
|
||||
inst, CONCAT(int, DT_INST_PROP(inst, drdy_int_pad), _gpios)), \
|
||||
"No GPIO pin defined for IIS328DQ DRDY interrupt");)) \
|
||||
IF_ENABLED(DT_INST_NODE_HAS_PROP(inst, threshold_int_pad), \
|
||||
(BUILD_ASSERT(DT_INST_NODE_HAS_PROP( \
|
||||
inst, CONCAT(int, DT_INST_PROP(inst, threshold_int_pad), \
|
||||
_gpios)), \
|
||||
"No GPIO pin defined for IIS328DQ threshold interrupt");)) \
|
||||
IF_ENABLED( \
|
||||
UTIL_AND(DT_INST_NODE_HAS_PROP(inst, drdy_int_pad), \
|
||||
DT_INST_NODE_HAS_PROP(inst, threshold_int_pad)), \
|
||||
(BUILD_ASSERT( \
|
||||
DT_INST_PROP(inst, drdy_int_pad) != \
|
||||
DT_INST_PROP(inst, threshold_int_pad), \
|
||||
"IIS328DQ DRDY interrupt and threshold interrupt cannot share a pin");))
|
||||
|
||||
DT_INST_FOREACH_STATUS_OKAY(IIS328DQ_DEFINE)
|
93
drivers/sensor/iis328dq/iis328dq.h
Normal file
93
drivers/sensor/iis328dq/iis328dq.h
Normal file
|
@ -0,0 +1,93 @@
|
|||
/* ST Microelectronics IIS328DQ 3-axis accelerometer driver
|
||||
*
|
||||
* Copyright (c) 2020 STMicroelectronics
|
||||
* Copyright (c) 2024 SILA Embedded Solutions GmbH
|
||||
*
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
*
|
||||
* Datasheet:
|
||||
* https://www.st.com/resource/en/datasheet/iis328dq.pdf
|
||||
*/
|
||||
|
||||
#ifndef ZEPHYR_DRIVERS_SENSOR_IIS328DQ_IIS328DQ_H_
|
||||
#define ZEPHYR_DRIVERS_SENSOR_IIS328DQ_IIS328DQ_H_
|
||||
|
||||
#include <zephyr/drivers/gpio.h>
|
||||
#include <zephyr/sys/util.h>
|
||||
#include <zephyr/drivers/sensor.h>
|
||||
#include <stmemsc.h>
|
||||
#include "iis328dq_reg.h"
|
||||
|
||||
#if DT_ANY_INST_ON_BUS_STATUS_OKAY(spi)
|
||||
#include <zephyr/drivers/spi.h>
|
||||
#endif /* DT_ANY_INST_ON_BUS_STATUS_OKAY(spi) */
|
||||
|
||||
#if DT_ANY_INST_ON_BUS_STATUS_OKAY(i2c)
|
||||
#include <zephyr/drivers/i2c.h>
|
||||
#endif /* DT_ANY_INST_ON_BUS_STATUS_OKAY(i2c) */
|
||||
|
||||
/**
|
||||
* struct iis328dq_dev_config - iis328dq hw configuration
|
||||
* @bus_name: Pointer to bus master identifier.
|
||||
* @pm: Power mode (lis2dh_powermode).
|
||||
* @irq_dev_name: Pointer to GPIO PORT identifier.
|
||||
* @irq_pin: GPIO pin number connected to sensor int pin.
|
||||
* @drdy_int: Sensor drdy int (int1/int2).
|
||||
*/
|
||||
struct iis328dq_config {
|
||||
stmdev_ctx_t ctx;
|
||||
union {
|
||||
#if DT_ANY_INST_ON_BUS_STATUS_OKAY(i2c)
|
||||
const struct i2c_dt_spec i2c;
|
||||
#endif
|
||||
#if DT_ANY_INST_ON_BUS_STATUS_OKAY(spi)
|
||||
const struct spi_dt_spec spi;
|
||||
#endif
|
||||
} stmemsc_cfg;
|
||||
uint8_t range;
|
||||
#ifdef CONFIG_IIS328DQ_TRIGGER
|
||||
const struct gpio_dt_spec gpio_int1;
|
||||
const struct gpio_dt_spec gpio_int2;
|
||||
/* interrupt pad to be used for DRDY interrupts, or -1 if not configured */
|
||||
int8_t drdy_pad;
|
||||
#ifdef CONFIG_IIS328DQ_THRESHOLD
|
||||
/* interrupt pad to be used for threshold interrupts, or -1 if not configured */
|
||||
int8_t threshold_pad;
|
||||
#endif /* CONFIG_IIS328DQ_THRESHOLD */
|
||||
#endif /* CONFIG_IIS328DQ_TRIGGER */
|
||||
};
|
||||
|
||||
/* sensor data */
|
||||
struct iis328dq_data {
|
||||
const struct device *dev;
|
||||
int16_t acc[3];
|
||||
|
||||
/* sensitivity in mg/LSB */
|
||||
uint8_t gain;
|
||||
|
||||
#ifdef CONFIG_IIS328DQ_TRIGGER
|
||||
struct gpio_callback int1_cb;
|
||||
struct gpio_callback int2_cb;
|
||||
sensor_trigger_handler_t drdy_handler;
|
||||
const struct sensor_trigger *drdy_trig;
|
||||
#ifdef CONFIG_IIS328DQ_THRESHOLD
|
||||
sensor_trigger_handler_t threshold_handler;
|
||||
const struct sensor_trigger *threshold_trig;
|
||||
#endif /* CONFIG_IIS328DQ_THRESHOLD */
|
||||
#if defined(CONFIG_IIS328DQ_TRIGGER_OWN_THREAD)
|
||||
K_KERNEL_STACK_MEMBER(thread_stack, CONFIG_IIS328DQ_THREAD_STACK_SIZE);
|
||||
struct k_thread thread;
|
||||
struct k_sem gpio_sem;
|
||||
#elif defined(CONFIG_IIS328DQ_TRIGGER_GLOBAL_THREAD)
|
||||
struct k_work work;
|
||||
#endif /* CONFIG_IIS328DQ_TRIGGER_GLOBAL_THREAD */
|
||||
#endif /* CONFIG_IIS328DQ_TRIGGER */
|
||||
};
|
||||
|
||||
#ifdef CONFIG_IIS328DQ_TRIGGER
|
||||
int iis328dq_init_interrupt(const struct device *dev);
|
||||
int iis328dq_trigger_set(const struct device *dev, const struct sensor_trigger *trig,
|
||||
sensor_trigger_handler_t handler);
|
||||
#endif /* CONFIG_IIS328DQ_TRIGGER */
|
||||
|
||||
#endif /* ZEPHYR_DRIVERS_SENSOR_IIS328DQ_IIS328DQ_H_ */
|
332
drivers/sensor/iis328dq/iis328dq_trigger.c
Normal file
332
drivers/sensor/iis328dq/iis328dq_trigger.c
Normal file
|
@ -0,0 +1,332 @@
|
|||
/* ST Microelectronics IIS328DQ 3-axis accelerometer driver
|
||||
*
|
||||
* Copyright (c) 2020 STMicroelectronics
|
||||
* Copyright (c) 2024 SILA Embedded Solutions GmbH
|
||||
*
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
*
|
||||
* Datasheet:
|
||||
* https://www.st.com/resource/en/datasheet/iis328dq.pdf
|
||||
*/
|
||||
|
||||
#define DT_DRV_COMPAT st_iis328dq
|
||||
|
||||
#include <zephyr/kernel.h>
|
||||
#include <zephyr/drivers/sensor.h>
|
||||
#include <zephyr/drivers/gpio.h>
|
||||
#include <zephyr/logging/log.h>
|
||||
|
||||
#include "iis328dq.h"
|
||||
|
||||
LOG_MODULE_DECLARE(IIS328DQ, CONFIG_SENSOR_LOG_LEVEL);
|
||||
|
||||
static int iis328dq_set_int_pad_state(const struct device *dev, uint8_t pad, bool enable)
|
||||
{
|
||||
const struct iis328dq_config *cfg = dev->config;
|
||||
|
||||
int state = enable ? GPIO_INT_EDGE_TO_ACTIVE : GPIO_INT_DISABLE;
|
||||
|
||||
if (pad == 1) {
|
||||
return gpio_pin_interrupt_configure_dt(&cfg->gpio_int1, state);
|
||||
} else if (pad == 2) {
|
||||
return gpio_pin_interrupt_configure_dt(&cfg->gpio_int2, state);
|
||||
} else {
|
||||
return -EINVAL;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* iis328dq_enable_int - enable selected int pin to generate interrupt
|
||||
*/
|
||||
static int iis328dq_enable_int(const struct device *dev, const struct sensor_trigger *trig,
|
||||
int enable)
|
||||
{
|
||||
const struct iis328dq_config *cfg = dev->config;
|
||||
stmdev_ctx_t *ctx = (stmdev_ctx_t *)&cfg->ctx;
|
||||
|
||||
switch (trig->type) {
|
||||
case SENSOR_TRIG_DATA_READY:
|
||||
if (cfg->drdy_pad == 1) {
|
||||
/* route DRDY to PAD1 */
|
||||
if (iis328dq_pin_int1_route_set(ctx, IIS328DQ_PAD1_DRDY) != 0) {
|
||||
return -EIO;
|
||||
}
|
||||
} else if (cfg->drdy_pad == 2) {
|
||||
/* route DRDY to PAD2 */
|
||||
if (iis328dq_pin_int2_route_set(ctx, IIS328DQ_PAD2_DRDY) != 0) {
|
||||
return -EIO;
|
||||
}
|
||||
} else {
|
||||
LOG_ERR("No interrupt pin configured for DRDY in devicetree");
|
||||
return -ENOTSUP;
|
||||
}
|
||||
return iis328dq_set_int_pad_state(dev, cfg->drdy_pad, enable);
|
||||
#ifdef CONFIG_IIS328DQ_THRESHOLD
|
||||
case SENSOR_TRIG_THRESHOLD: {
|
||||
/* set up internal INT1 for lower thresholds */
|
||||
int1_on_th_conf_t int1_conf = {0};
|
||||
|
||||
switch (trig->chan) {
|
||||
case SENSOR_CHAN_ACCEL_X:
|
||||
int1_conf.int1_xlie = 1;
|
||||
break;
|
||||
case SENSOR_CHAN_ACCEL_Y:
|
||||
int1_conf.int1_ylie = 1;
|
||||
break;
|
||||
case SENSOR_CHAN_ACCEL_Z:
|
||||
int1_conf.int1_zlie = 1;
|
||||
break;
|
||||
case SENSOR_CHAN_ACCEL_XYZ:
|
||||
int1_conf.int1_xlie = 1;
|
||||
int1_conf.int1_ylie = 1;
|
||||
int1_conf.int1_zlie = 1;
|
||||
break;
|
||||
default:
|
||||
LOG_ERR("Invalid sensor channel %d", trig->chan);
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
if (iis328dq_int1_on_threshold_conf_set(ctx, int1_conf) != 0) {
|
||||
return -EIO;
|
||||
}
|
||||
|
||||
/* set up internal INT2 for uppper thresholds */
|
||||
int2_on_th_conf_t int2_conf = {0};
|
||||
|
||||
int2_conf.int2_xhie = int1_conf.int1_xlie;
|
||||
int2_conf.int2_yhie = int1_conf.int1_ylie;
|
||||
int2_conf.int2_zhie = int1_conf.int1_zlie;
|
||||
if (iis328dq_int2_on_threshold_conf_set(ctx, int2_conf) != 0) {
|
||||
return -EIO;
|
||||
}
|
||||
|
||||
if (cfg->threshold_pad == 1) {
|
||||
/* route both internal interrupts to PAD1 */
|
||||
if (iis328dq_pin_int1_route_set(ctx, IIS328DQ_PAD1_INT1_OR_INT2_SRC) != 0) {
|
||||
return -EIO;
|
||||
}
|
||||
} else if (cfg->threshold_pad == 2) {
|
||||
/* route both internal interrupts to PAD2 */
|
||||
if (iis328dq_pin_int2_route_set(ctx, IIS328DQ_PAD2_INT1_OR_INT2_SRC) != 0) {
|
||||
return -EIO;
|
||||
}
|
||||
} else {
|
||||
LOG_ERR("No interrupt pin configured for DRDY in devicetree");
|
||||
return -ENOTSUP;
|
||||
}
|
||||
return iis328dq_set_int_pad_state(dev, cfg->threshold_pad, enable);
|
||||
}
|
||||
#endif /* CONFIG_IIS328DQ_THRESHOLD */
|
||||
default:
|
||||
LOG_ERR("Unsupported trigger interrupt route %d", trig->type);
|
||||
return -ENOTSUP;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* iis328dq_trigger_set - link external trigger to event data ready
|
||||
*/
|
||||
int iis328dq_trigger_set(const struct device *dev, const struct sensor_trigger *trig,
|
||||
sensor_trigger_handler_t handler)
|
||||
{
|
||||
const struct iis328dq_config *cfg = dev->config;
|
||||
stmdev_ctx_t *ctx = (stmdev_ctx_t *)&cfg->ctx;
|
||||
struct iis328dq_data *iis328dq = dev->data;
|
||||
int16_t raw[3];
|
||||
int state = (handler != NULL) ? PROPERTY_ENABLE : PROPERTY_DISABLE;
|
||||
|
||||
if (!cfg->gpio_int1.port && !cfg->gpio_int2.port) {
|
||||
/* no interrupts configured */
|
||||
return -ENOTSUP;
|
||||
}
|
||||
|
||||
switch (trig->type) {
|
||||
case SENSOR_TRIG_DATA_READY:
|
||||
iis328dq->drdy_handler = handler;
|
||||
iis328dq->drdy_trig = trig;
|
||||
if (state) {
|
||||
/* dummy read: re-trigger interrupt */
|
||||
iis328dq_acceleration_raw_get(ctx, raw);
|
||||
}
|
||||
break;
|
||||
#ifdef CONFIG_IIS328DQ_THRESHOLD
|
||||
case SENSOR_TRIG_THRESHOLD:
|
||||
iis328dq->threshold_handler = handler;
|
||||
iis328dq->threshold_trig = trig;
|
||||
break;
|
||||
#endif /* CONFIG_IIS328DQ_THRESHOLD */
|
||||
default:
|
||||
LOG_ERR("Unsupported sensor trigger");
|
||||
return -ENOTSUP;
|
||||
}
|
||||
|
||||
return iis328dq_enable_int(dev, trig, state);
|
||||
}
|
||||
|
||||
/**
|
||||
* iis328dq_handle_interrupt - handle the drdy event
|
||||
* read data and call handler if registered any
|
||||
*/
|
||||
static void iis328dq_handle_interrupt(const struct device *dev)
|
||||
{
|
||||
const struct iis328dq_config *cfg = dev->config;
|
||||
struct iis328dq_data *data = dev->data;
|
||||
stmdev_ctx_t *ctx = (stmdev_ctx_t *)&cfg->ctx;
|
||||
iis328dq_status_reg_t status;
|
||||
iis328dq_int1_src_t sources1;
|
||||
iis328dq_int2_src_t sources2;
|
||||
|
||||
iis328dq_status_reg_get(ctx, &status);
|
||||
|
||||
if (status.zyxda) {
|
||||
if (data->drdy_handler) {
|
||||
data->drdy_handler(dev, data->drdy_trig);
|
||||
}
|
||||
|
||||
iis328dq_set_int_pad_state(dev, cfg->drdy_pad, true);
|
||||
}
|
||||
#ifdef CONFIG_IIS328DQ_THRESHOLD
|
||||
iis328dq_int1_src_get(ctx, &sources1);
|
||||
iis328dq_int2_src_get(ctx, &sources2);
|
||||
if (sources1.ia || sources2.ia) {
|
||||
if (data->threshold_handler) {
|
||||
data->threshold_handler(dev, data->threshold_trig);
|
||||
}
|
||||
|
||||
iis328dq_set_int_pad_state(dev, cfg->threshold_pad, true);
|
||||
}
|
||||
#endif /* CONFIG_IIS328DQ_THRESHOLD */
|
||||
}
|
||||
|
||||
static void iis328dq_int1_gpio_callback(const struct device *dev, struct gpio_callback *cb,
|
||||
uint32_t pins)
|
||||
{
|
||||
struct iis328dq_data *iis328dq = CONTAINER_OF(cb, struct iis328dq_data, int1_cb);
|
||||
|
||||
ARG_UNUSED(pins);
|
||||
|
||||
iis328dq_set_int_pad_state(iis328dq->dev, 1, true);
|
||||
|
||||
#if defined(CONFIG_IIS328DQ_TRIGGER_OWN_THREAD)
|
||||
k_sem_give(&iis328dq->gpio_sem);
|
||||
#elif defined(CONFIG_IIS328DQ_TRIGGER_GLOBAL_THREAD)
|
||||
k_work_submit(&iis328dq->work);
|
||||
#endif /* CONFIG_IIS328DQ_TRIGGER_OWN_THREAD */
|
||||
}
|
||||
|
||||
static void iis328dq_int2_gpio_callback(const struct device *dev, struct gpio_callback *cb,
|
||||
uint32_t pins)
|
||||
{
|
||||
struct iis328dq_data *iis328dq = CONTAINER_OF(cb, struct iis328dq_data, int2_cb);
|
||||
|
||||
ARG_UNUSED(pins);
|
||||
|
||||
iis328dq_set_int_pad_state(iis328dq->dev, 2, true);
|
||||
|
||||
#if defined(CONFIG_IIS328DQ_TRIGGER_OWN_THREAD)
|
||||
k_sem_give(&iis328dq->gpio_sem);
|
||||
#elif defined(CONFIG_IIS328DQ_TRIGGER_GLOBAL_THREAD)
|
||||
k_work_submit(&iis328dq->work);
|
||||
#endif /* CONFIG_IIS328DQ_TRIGGER_OWN_THREAD */
|
||||
}
|
||||
|
||||
#ifdef CONFIG_IIS328DQ_TRIGGER_OWN_THREAD
|
||||
static void iis328dq_thread(void *p1, void *p2, void *p3)
|
||||
{
|
||||
ARG_UNUSED(p2);
|
||||
ARG_UNUSED(p3);
|
||||
|
||||
struct iis328dq_data *iis328dq = p1;
|
||||
|
||||
while (1) {
|
||||
k_sem_take(&iis328dq->gpio_sem, K_FOREVER);
|
||||
iis328dq_handle_interrupt(iis328dq->dev);
|
||||
}
|
||||
}
|
||||
#endif /* CONFIG_IIS328DQ_TRIGGER_OWN_THREAD */
|
||||
|
||||
#ifdef CONFIG_IIS328DQ_TRIGGER_GLOBAL_THREAD
|
||||
static void iis328dq_work_cb(struct k_work *work)
|
||||
{
|
||||
struct iis328dq_data *iis328dq = CONTAINER_OF(work, struct iis328dq_data, work);
|
||||
|
||||
iis328dq_handle_interrupt(iis328dq->dev);
|
||||
}
|
||||
#endif /* CONFIG_IIS328DQ_TRIGGER_GLOBAL_THREAD */
|
||||
|
||||
int iis328dq_init_interrupt(const struct device *dev)
|
||||
{
|
||||
struct iis328dq_data *iis328dq = dev->data;
|
||||
const struct iis328dq_config *cfg = dev->config;
|
||||
stmdev_ctx_t *ctx = (stmdev_ctx_t *)&cfg->ctx;
|
||||
int ret;
|
||||
|
||||
if (!cfg->gpio_int1.port && !cfg->gpio_int2.port) {
|
||||
/* no interrupts configured, nothing to do */
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* setup data ready gpio interrupt (INT1 and INT2) */
|
||||
if (cfg->gpio_int1.port) {
|
||||
if (!gpio_is_ready_dt(&cfg->gpio_int1)) {
|
||||
LOG_ERR("INT_1 pin is not ready");
|
||||
return -EINVAL;
|
||||
}
|
||||
}
|
||||
if (cfg->gpio_int2.port) {
|
||||
if (!gpio_is_ready_dt(&cfg->gpio_int2)) {
|
||||
LOG_ERR("INT_2 pin is not ready");
|
||||
return -EINVAL;
|
||||
}
|
||||
}
|
||||
|
||||
#if defined(CONFIG_IIS328DQ_TRIGGER_OWN_THREAD)
|
||||
k_sem_init(&iis328dq->gpio_sem, 0, K_SEM_MAX_LIMIT);
|
||||
|
||||
k_thread_create(&iis328dq->thread, iis328dq->thread_stack,
|
||||
CONFIG_IIS328DQ_THREAD_STACK_SIZE, iis328dq_thread, iis328dq, NULL, NULL,
|
||||
K_PRIO_COOP(CONFIG_IIS328DQ_THREAD_PRIORITY), 0, K_NO_WAIT);
|
||||
#elif defined(CONFIG_IIS328DQ_TRIGGER_GLOBAL_THREAD)
|
||||
iis328dq->work.handler = iis328dq_work_cb;
|
||||
#endif /* CONFIG_IIS328DQ_TRIGGER_OWN_THREAD */
|
||||
|
||||
if (cfg->gpio_int1.port) {
|
||||
ret = gpio_pin_configure_dt(&cfg->gpio_int1, GPIO_INPUT);
|
||||
if (ret < 0) {
|
||||
LOG_ERR("Could not configure INT_1 gpio");
|
||||
return ret;
|
||||
}
|
||||
gpio_init_callback(&iis328dq->int1_cb, iis328dq_int1_gpio_callback,
|
||||
BIT(cfg->gpio_int1.pin));
|
||||
if (gpio_add_callback(cfg->gpio_int1.port, &iis328dq->int1_cb) < 0) {
|
||||
LOG_ERR("Could not set INT1 callback");
|
||||
return -EIO;
|
||||
}
|
||||
}
|
||||
|
||||
if (cfg->gpio_int2.port) {
|
||||
ret = gpio_pin_configure_dt(&cfg->gpio_int2, GPIO_INPUT);
|
||||
if (ret < 0) {
|
||||
LOG_ERR("Could not configure INT_2 gpio");
|
||||
return ret;
|
||||
}
|
||||
gpio_init_callback(&iis328dq->int2_cb, iis328dq_int2_gpio_callback,
|
||||
BIT(cfg->gpio_int2.pin));
|
||||
if (gpio_add_callback(cfg->gpio_int2.port, &iis328dq->int2_cb) < 0) {
|
||||
LOG_ERR("Could not set INT2 callback");
|
||||
return -EIO;
|
||||
}
|
||||
}
|
||||
|
||||
if (iis328dq_int1_notification_set(ctx, IIS328DQ_INT1_PULSED) != 0) {
|
||||
return -EIO;
|
||||
}
|
||||
|
||||
if (iis328dq_int2_notification_set(ctx, IIS328DQ_INT2_PULSED) != 0) {
|
||||
return -EIO;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
61
dts/bindings/sensor/st,iis328dq-common.yaml
Normal file
61
dts/bindings/sensor/st,iis328dq-common.yaml
Normal file
|
@ -0,0 +1,61 @@
|
|||
# Copyright (c) 2018 STMicroelectronics
|
||||
# Copyright (c) 2024 SILA Embedded Solutions GmbH
|
||||
# SPDX-License-Identifier: Apache-2.0
|
||||
|
||||
include: sensor-device.yaml
|
||||
|
||||
properties:
|
||||
int1-gpios:
|
||||
type: phandle-array
|
||||
description: |
|
||||
INT_1 pin
|
||||
|
||||
This pin defaults to active high when produced by the sensor. The property value should ensure
|
||||
the flags properly describe the signal that is presented to the driver.
|
||||
|
||||
int2-gpios:
|
||||
type: phandle-array
|
||||
description: |
|
||||
INT_2 pin
|
||||
|
||||
This pin defaults to active high when produced by the sensor. The property value should ensure
|
||||
the flags properly describe the signal that is presented to the driver.
|
||||
|
||||
drdy-int-pad:
|
||||
type: int
|
||||
enum: [1, 2]
|
||||
description: |
|
||||
Select DRDY pin number (1 or 2).
|
||||
|
||||
This number represents which of the two interrupt pins (INT_1 or INT_2), if any, the DRDY
|
||||
interrupt should be generated from. If this property is not specified, no data ready
|
||||
interrupts can be registered.
|
||||
|
||||
- 1 # drdy is generated on INT1
|
||||
- 2 # drdy is generated on INT2
|
||||
|
||||
threshold-int-pad:
|
||||
type: int
|
||||
enum: [1, 2]
|
||||
description: |
|
||||
Select threshold interrupt pin number (1 or 2).
|
||||
|
||||
This number represents which of the two interrupt pins (INT_1 or INT_2), if any, the threshold
|
||||
interrupt should be generated from. If this property is not specified, no threshold interrupts
|
||||
can be registered.
|
||||
|
||||
- 1 # threshold interrupt is generated on INT1
|
||||
- 2 # threshold interrupt is generated on INT2
|
||||
|
||||
range:
|
||||
type: int
|
||||
default: 2
|
||||
description: |
|
||||
Range in g. Default is power-up configuration.
|
||||
|
||||
- 16 # 16g (1.952 mg/LSB)
|
||||
- 8 # 8g (0.976 mg/LSB)
|
||||
- 4 # 4g (0.488 mg/LSB)
|
||||
- 2 # 2g (0.244 mg/LSB)
|
||||
|
||||
enum: [16, 8, 4, 2]
|
10
dts/bindings/sensor/st,iis328dq-i2c.yaml
Normal file
10
dts/bindings/sensor/st,iis328dq-i2c.yaml
Normal file
|
@ -0,0 +1,10 @@
|
|||
# Copyright (c) 2018 STMicroelectronics
|
||||
# Copyright (c) 2024 SILA Embedded Solutions GmbH
|
||||
# SPDX-License-Identifier: Apache-2.0
|
||||
|
||||
description: |
|
||||
STMicroelectronics IIS328DQ accelerometer accessed through I2C bus
|
||||
|
||||
compatible: "st,iis328dq"
|
||||
|
||||
include: ["i2c-device.yaml", "st,iis328dq-common.yaml"]
|
10
dts/bindings/sensor/st,iis328dq-spi.yaml
Normal file
10
dts/bindings/sensor/st,iis328dq-spi.yaml
Normal file
|
@ -0,0 +1,10 @@
|
|||
# Copyright (c) 2019 STMicroelectronics
|
||||
# Copyright (c) 2024 SILA Embedded Solutions GmbH
|
||||
# SPDX-License-Identifier: Apache-2.0
|
||||
|
||||
description: |
|
||||
STMicroelectronics IIS328DQ accelerometer accessed through SPI bus
|
||||
|
||||
compatible: "st,iis328dq"
|
||||
|
||||
include: ["spi-device.yaml", "st,iis328dq-common.yaml"]
|
|
@ -120,13 +120,14 @@
|
|||
<&test_gpio 0 0>,
|
||||
<&test_gpio 0 0>,
|
||||
<&test_gpio 0 0>,
|
||||
<&test_gpio 0 0>, /* 0x25 */
|
||||
<&test_gpio 0 0>, /* 0x26 */
|
||||
<&test_gpio 0 0>, /* 0x27 */
|
||||
<&test_gpio 0 0>, /* 0x28 */
|
||||
<&test_gpio 0 0>, /* 0x29 */
|
||||
<&test_gpio 0 0>, /* 0x2A */
|
||||
<&test_gpio 0 0>; /* 0x2B */
|
||||
<&test_gpio 0 0>,
|
||||
<&test_gpio 0 0>,
|
||||
<&test_gpio 0 0>,
|
||||
<&test_gpio 0 0>,
|
||||
<&test_gpio 0 0>,
|
||||
<&test_gpio 0 0>,
|
||||
<&test_gpio 0 0>,
|
||||
<&test_gpio 0 0>; /* 0x2C */
|
||||
|
||||
#include "spi.dtsi"
|
||||
};
|
||||
|
|
|
@ -1011,3 +1011,11 @@ test_i2c_am2301b: am2301b@89 {
|
|||
reg = <0x89>;
|
||||
status = "okay";
|
||||
};
|
||||
|
||||
test_i2c_iis328dq: iis328dq@8a {
|
||||
compatible = "st,iis328dq";
|
||||
status = "okay";
|
||||
reg = <0x8a>;
|
||||
int2-gpios = <&test_gpio 0 0>;
|
||||
threshold-int-pad = <2>;
|
||||
};
|
||||
|
|
|
@ -352,3 +352,12 @@ test_spi_bd8lb600fs: bd8lb600fs@2b {
|
|||
#sensor-cells = <0>;
|
||||
};
|
||||
};
|
||||
|
||||
test_spi_iis328dq: iis328dq@2c {
|
||||
compatible = "st,iis328dq";
|
||||
status = "okay";
|
||||
reg = <0x2c>;
|
||||
spi-max-frequency = <0>;
|
||||
int1-gpios = <&test_gpio 0 0>;
|
||||
drdy-int-pad = <1>;
|
||||
};
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue