drivers: sensor: lsm6dsv16x: support setting and getting wake attributes

Adds support for the SENSOR_ATTR_SLOPE_TH and SENSOR_ATTR_SLOPE_DUR
attributes These set the sensitivity for the SENSOR_TRIG_DELTA trigger
which uses the sensor's wakeup feature.

Signed-off-by: Corey Wharton <xodus7@cwharton.com>
This commit is contained in:
Corey Wharton 2025-02-06 22:31:10 -08:00 committed by Benjamin Cabé
commit 9d262d0698

View file

@ -234,6 +234,55 @@ static int lsm6dsv16x_accel_range_set(const struct device *dev, int32_t range)
return 0; return 0;
} }
#define LSM6DSV16X_WU_INACT_THS_W_MAX 5
#define LSM6DSV16X_WAKE_UP_THS_MAX 0x3FU
static const float wu_inact_ths_w_lsb[] = {7.8125f, 15.625f, 31.25f, 62.5f, 125.0f, 250.0f};
static int lsm6dsv16x_accel_wake_threshold_set(const struct device *dev,
const struct sensor_value *val)
{
const struct lsm6dsv16x_config *cfg = dev->config;
stmdev_ctx_t *ctx = (stmdev_ctx_t *)&cfg->ctx;
lsm6dsv16x_act_thresholds_t thresholds;
if (lsm6dsv16x_act_thresholds_get(ctx, &thresholds) < 0) {
LOG_DBG("failed to get thresholds");
return -EIO;
}
float val_mg = sensor_ms2_to_ug(val) / 1000.0f;
thresholds.inactivity_cfg.wu_inact_ths_w = LSM6DSV16X_WU_INACT_THS_W_MAX;
thresholds.threshold = LSM6DSV16X_WAKE_UP_THS_MAX;
for (uint8_t i = 0; i <= LSM6DSV16X_WU_INACT_THS_W_MAX; i++) {
if (val_mg < (wu_inact_ths_w_lsb[i] * (float)LSM6DSV16X_WAKE_UP_THS_MAX)) {
thresholds.inactivity_cfg.wu_inact_ths_w = i;
thresholds.threshold = (uint8_t)(val_mg / wu_inact_ths_w_lsb[i]);
break;
}
}
return lsm6dsv16x_act_thresholds_set(ctx, &thresholds);
}
static int lsm6dsv16x_accel_wake_duration_set(const struct device *dev,
const struct sensor_value *val)
{
const struct lsm6dsv16x_config *cfg = dev->config;
stmdev_ctx_t *ctx = (stmdev_ctx_t *)&cfg->ctx;
lsm6dsv16x_act_thresholds_t thresholds;
if (lsm6dsv16x_act_thresholds_get(ctx, &thresholds) < 0) {
LOG_DBG("failed to get thresholds");
return -EIO;
}
thresholds.duration = MIN(val->val1, 3);
return lsm6dsv16x_act_thresholds_set(ctx, &thresholds);
}
static int lsm6dsv16x_accel_config(const struct device *dev, static int lsm6dsv16x_accel_config(const struct device *dev,
enum sensor_channel chan, enum sensor_channel chan,
enum sensor_attribute attr, enum sensor_attribute attr,
@ -248,6 +297,10 @@ static int lsm6dsv16x_accel_config(const struct device *dev,
return lsm6dsv16x_accel_range_set(dev, sensor_ms2_to_g(val)); return lsm6dsv16x_accel_range_set(dev, sensor_ms2_to_g(val));
case SENSOR_ATTR_SAMPLING_FREQUENCY: case SENSOR_ATTR_SAMPLING_FREQUENCY:
return lsm6dsv16x_accel_odr_set(dev, val->val1); return lsm6dsv16x_accel_odr_set(dev, val->val1);
case SENSOR_ATTR_SLOPE_TH:
return lsm6dsv16x_accel_wake_threshold_set(dev, val);
case SENSOR_ATTR_SLOPE_DUR:
return lsm6dsv16x_accel_wake_duration_set(dev, val);
case SENSOR_ATTR_CONFIGURATION: case SENSOR_ATTR_CONFIGURATION:
switch (val->val1) { switch (val->val1) {
case 0: /* High Performance */ case 0: /* High Performance */
@ -402,6 +455,43 @@ static int lsm6dsv16x_attr_set(const struct device *dev,
return 0; return 0;
} }
static int lsm6dsv16x_accel_wake_threshold_get(const struct device *dev, struct sensor_value *val)
{
const struct lsm6dsv16x_config *cfg = dev->config;
stmdev_ctx_t *ctx = (stmdev_ctx_t *)&cfg->ctx;
lsm6dsv16x_act_thresholds_t thresholds;
float val_mg;
if (lsm6dsv16x_act_thresholds_get(ctx, &thresholds) < 0) {
LOG_DBG("failed to get thresholds");
return -EIO;
}
val_mg = wu_inact_ths_w_lsb[thresholds.inactivity_cfg.wu_inact_ths_w];
val_mg *= (float)thresholds.threshold;
sensor_ug_to_ms2(1000.0f * val_mg, val);
return 0;
}
static int lsm6dsv16x_accel_wake_duration_get(const struct device *dev, struct sensor_value *val)
{
const struct lsm6dsv16x_config *cfg = dev->config;
stmdev_ctx_t *ctx = (stmdev_ctx_t *)&cfg->ctx;
lsm6dsv16x_act_thresholds_t thresholds;
if (lsm6dsv16x_act_thresholds_get(ctx, &thresholds) < 0) {
LOG_DBG("failed to get thresholds");
return -EIO;
}
val->val1 = thresholds.duration;
val->val2 = 0;
return 0;
}
static int lsm6dsv16x_accel_get_config(const struct device *dev, static int lsm6dsv16x_accel_get_config(const struct device *dev,
enum sensor_channel chan, enum sensor_channel chan,
enum sensor_attribute attr, enum sensor_attribute attr,
@ -429,6 +519,10 @@ static int lsm6dsv16x_accel_get_config(const struct device *dev,
val->val2 = 0; val->val2 = 0;
break; break;
} }
case SENSOR_ATTR_SLOPE_TH:
return lsm6dsv16x_accel_wake_threshold_get(dev, val);
case SENSOR_ATTR_SLOPE_DUR:
return lsm6dsv16x_accel_wake_duration_get(dev, val);
case SENSOR_ATTR_CONFIGURATION: { case SENSOR_ATTR_CONFIGURATION: {
lsm6dsv16x_xl_mode_t mode; lsm6dsv16x_xl_mode_t mode;
@ -529,10 +623,8 @@ static int lsm6dsv16x_gyro_get_config(const struct device *dev,
return 0; return 0;
} }
static int lsm6dsv16x_attr_get(const struct device *dev, static int lsm6dsv16x_attr_get(const struct device *dev, enum sensor_channel chan,
enum sensor_channel chan, enum sensor_attribute attr, struct sensor_value *val)
enum sensor_attribute attr,
struct sensor_value *val)
{ {
if (!lsm6dsv16x_is_active(dev)) { if (!lsm6dsv16x_is_active(dev)) {
return -EBUSY; return -EBUSY;