drivers: sensor: lis2dw12: add inactivity detection
Add inactivity mode or stationary detection Signed-off-by: Andrew Sonzogni <andrew@safehear.fr>
This commit is contained in:
parent
c74dd3ee74
commit
70de35d9c9
6 changed files with 163 additions and 34 deletions
|
@ -63,10 +63,15 @@ config LIS2DW12_TAP
|
|||
|
||||
endif # LIS2DW12_TRIGGER
|
||||
|
||||
config LIS2DW12_THRESHOLD
|
||||
bool "Wakeup threshold trigger (via interrupt)"
|
||||
config LIS2DW12_SLEEP
|
||||
bool "Sleep mode"
|
||||
help
|
||||
Enable the wakeup threshold trigger feature.
|
||||
Enable sleep (inactivity) mode with ODR change when detected
|
||||
|
||||
config LIS2DW12_WAKEUP
|
||||
bool "Wakeup detection (via interrupt)"
|
||||
help
|
||||
Enable the wakeup detection feature.
|
||||
The wake-up interrupt signal is generated if a certain number of
|
||||
consecutive data exceed the configured threshold (config in DT).
|
||||
The threshold is applied to both positive and negative data: for
|
||||
|
|
|
@ -187,7 +187,7 @@ static inline int32_t sensor_ms2_to_mg(const struct sensor_value *ms2)
|
|||
}
|
||||
}
|
||||
|
||||
#if CONFIG_LIS2DW12_THRESHOLD
|
||||
#if (CONFIG_LIS2DW12_SLEEP || CONFIG_LIS2DW12_WAKEUP)
|
||||
|
||||
/* Converts a lis2dw12_fs_t range to its value in milli-g
|
||||
* Range can be 2/4/8/16G
|
||||
|
@ -290,27 +290,50 @@ static int lis2dw12_attr_set_ff_dur(const struct device *dev,
|
|||
}
|
||||
#endif
|
||||
|
||||
#ifdef CONFIG_LIS2DW12_SLEEP
|
||||
static int lis2dw12_attr_set_act_mode(const struct device *dev,
|
||||
enum sensor_channel chan,
|
||||
enum sensor_attribute attr,
|
||||
const struct sensor_value *val)
|
||||
{
|
||||
const struct lis2dw12_device_config *cfg = dev->config;
|
||||
struct lis2dw12_data *lis2dw12 = dev->data;
|
||||
stmdev_ctx_t *ctx = (stmdev_ctx_t *)&cfg->ctx;
|
||||
lis2dw12_sleep_on_t sleep_val = val->val1 & 0x03U;
|
||||
|
||||
/* can only be set for all directions at once */
|
||||
if (chan != SENSOR_CHAN_ACCEL_XYZ) {
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
return lis2dw12_act_mode_set(ctx, sleep_val);
|
||||
}
|
||||
#endif
|
||||
|
||||
static int lis2dw12_attr_set(const struct device *dev,
|
||||
enum sensor_channel chan,
|
||||
enum sensor_attribute attr,
|
||||
const struct sensor_value *val)
|
||||
{
|
||||
#if CONFIG_LIS2DW12_THRESHOLD
|
||||
switch (attr) {
|
||||
#if (CONFIG_LIS2DW12_SLEEP || CONFIG_LIS2DW12_WAKEUP)
|
||||
case SENSOR_ATTR_UPPER_THRESH:
|
||||
case SENSOR_ATTR_LOWER_THRESH:
|
||||
return lis2dw12_attr_set_thresh(dev, chan, attr, val);
|
||||
#endif
|
||||
#ifdef CONFIG_LIS2DW12_FREEFALL
|
||||
case SENSOR_ATTR_FF_DUR:
|
||||
return lis2dw12_attr_set_ff_dur(dev, chan, attr, val);
|
||||
#endif
|
||||
#ifdef CONFIG_LIS2DW12_SLEEP
|
||||
case SENSOR_ATTR_FEATURE_MASK:
|
||||
return lis2dw12_attr_set_act_mode(dev, chan, attr, val);
|
||||
#endif
|
||||
default:
|
||||
/* Do nothing */
|
||||
break;
|
||||
}
|
||||
#endif
|
||||
|
||||
#ifdef CONFIG_LIS2DW12_FREEFALL
|
||||
if (attr == SENSOR_ATTR_FF_DUR) {
|
||||
return lis2dw12_attr_set_ff_dur(dev, chan, attr, val);
|
||||
}
|
||||
#endif
|
||||
|
||||
switch (chan) {
|
||||
case SENSOR_CHAN_ACCEL_X:
|
||||
|
@ -527,13 +550,20 @@ static int lis2dw12_init(const struct device *dev)
|
|||
return ret;
|
||||
}
|
||||
|
||||
#ifdef CONFIG_LIS2DW12_THRESHOLD
|
||||
#ifdef CONFIG_LIS2DW12_WAKEUP
|
||||
ret = lis2dw12_wkup_dur_set(ctx, cfg->wakeup_duration);
|
||||
if (ret < 0) {
|
||||
LOG_ERR("wakeup duration config error %d", ret);
|
||||
return ret;
|
||||
}
|
||||
#endif /* CONFIG_LIS2DW12_THRESHOLD */
|
||||
#endif /* CONFIG_LIS2DW12_WAKEUP */
|
||||
#ifdef CONFIG_LIS2DW12_SLEEP
|
||||
ret = lis2dw12_act_sleep_dur_set(ctx, cfg->sleep_duration);
|
||||
if (ret < 0) {
|
||||
LOG_ERR("sleep duration config error %d", ret);
|
||||
return ret;
|
||||
}
|
||||
#endif /* CONFIG_LIS2DW12_SLEEP */
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
@ -580,11 +610,18 @@ static int lis2dw12_init(const struct device *dev)
|
|||
#define LIS2DW12_CONFIG_FREEFALL(inst)
|
||||
#endif /* CONFIG_LIS2DW12_FREEFALL */
|
||||
|
||||
#ifdef CONFIG_LIS2DW12_THRESHOLD
|
||||
#define LIS2DW12_CONFIG_THRESHOLD(inst) \
|
||||
#ifdef CONFIG_LIS2DW12_WAKEUP
|
||||
#define LIS2DW12_CONFIG_WAKEUP(inst) \
|
||||
.wakeup_duration = DT_INST_PROP(inst, wakeup_duration),
|
||||
#else
|
||||
#define LIS2DW12_CONFIG_THRESHOLD(inst)
|
||||
#define LIS2DW12_CONFIG_WAKEUP(inst)
|
||||
#endif
|
||||
|
||||
#ifdef CONFIG_LIS2DW12_SLEEP
|
||||
#define LIS2DW12_CONFIG_SLEEP(inst) \
|
||||
.sleep_duration = DT_INST_PROP(inst, sleep_duration),
|
||||
#else
|
||||
#define LIS2DW12_CONFIG_SLEEP(inst)
|
||||
#endif
|
||||
|
||||
#ifdef CONFIG_LIS2DW12_TRIGGER
|
||||
|
@ -606,7 +643,8 @@ static int lis2dw12_init(const struct device *dev)
|
|||
.drdy_pulsed = DT_INST_PROP(inst, drdy_pulsed), \
|
||||
LIS2DW12_CONFIG_TAP(inst) \
|
||||
LIS2DW12_CONFIG_FREEFALL(inst) \
|
||||
LIS2DW12_CONFIG_THRESHOLD(inst) \
|
||||
LIS2DW12_CONFIG_WAKEUP(inst) \
|
||||
LIS2DW12_CONFIG_SLEEP(inst) \
|
||||
COND_CODE_1(DT_INST_NODE_HAS_PROP(inst, irq_gpios), \
|
||||
(LIS2DW12_CFG_IRQ(inst)), ())
|
||||
|
||||
|
|
|
@ -97,13 +97,16 @@ struct lis2dw12_device_config {
|
|||
uint8_t tap_latency;
|
||||
uint8_t tap_quiet;
|
||||
#endif /* CONFIG_LIS2DW12_TAP */
|
||||
#ifdef CONFIG_LIS2DW12_SLEEP
|
||||
uint8_t sleep_duration;
|
||||
#endif
|
||||
#ifdef CONFIG_LIS2DW12_FREEFALL
|
||||
uint8_t freefall_duration;
|
||||
uint8_t freefall_threshold;
|
||||
#endif /* CONFIG_LIS2DW12_FREEFALL */
|
||||
#ifdef CONFIG_LIS2DW12_THRESHOLD
|
||||
#ifdef CONFIG_LIS2DW12_WAKEUP
|
||||
uint8_t wakeup_duration;
|
||||
#endif /* CONFIG_LIS2DW12_THRESHOLD */
|
||||
#endif /* CONFIG_LIS2DW12_WAKEUP */
|
||||
#endif /* CONFIG_LIS2DW12_TRIGGER */
|
||||
};
|
||||
|
||||
|
@ -131,10 +134,14 @@ struct lis2dw12_data {
|
|||
sensor_trigger_handler_t double_tap_handler;
|
||||
const struct sensor_trigger *double_tap_trig;
|
||||
#endif /* CONFIG_LIS2DW12_TAP */
|
||||
#ifdef CONFIG_LIS2DW12_THRESHOLD
|
||||
sensor_trigger_handler_t threshold_handler;
|
||||
const struct sensor_trigger *threshold_trig;
|
||||
#endif /* CONFIG_LIS2DW12_THRESHOLD */
|
||||
#ifdef CONFIG_LIS2DW12_WAKEUP
|
||||
sensor_trigger_handler_t motion_handler;
|
||||
const struct sensor_trigger *motion_trig;
|
||||
#endif /* CONFIG_LIS2DW12_WAKEUP */
|
||||
#ifdef CONFIG_LIS2DW12_SLEEP
|
||||
sensor_trigger_handler_t stationary_handler;
|
||||
const struct sensor_trigger *stationary_trig;
|
||||
#endif
|
||||
#ifdef CONFIG_LIS2DW12_FREEFALL
|
||||
sensor_trigger_handler_t freefall_handler;
|
||||
const struct sensor_trigger *freefall_trig;
|
||||
|
|
|
@ -67,14 +67,14 @@ static int lis2dw12_enable_int(const struct device *dev,
|
|||
return lis2dw12_pin_int1_route_set(ctx,
|
||||
&int_route.ctrl4_int1_pad_ctrl);
|
||||
#endif /* CONFIG_LIS2DW12_TAP */
|
||||
#ifdef CONFIG_LIS2DW12_THRESHOLD
|
||||
#ifdef CONFIG_LIS2DW12_WAKEUP
|
||||
/**
|
||||
* Trigger fires when channel reading transitions configured
|
||||
* thresholds. The thresholds are configured via the @ref
|
||||
* SENSOR_ATTR_LOWER_THRESH and @ref SENSOR_ATTR_UPPER_THRESH
|
||||
* attributes.
|
||||
*/
|
||||
case SENSOR_TRIG_THRESHOLD:
|
||||
case SENSOR_TRIG_MOTION:
|
||||
LOG_DBG("Setting int1_wu: %d\n", enable);
|
||||
lis2dw12_pin_int1_route_get(ctx,
|
||||
&int_route.ctrl4_int1_pad_ctrl);
|
||||
|
@ -82,6 +82,21 @@ static int lis2dw12_enable_int(const struct device *dev,
|
|||
return lis2dw12_pin_int1_route_set(ctx,
|
||||
&int_route.ctrl4_int1_pad_ctrl);
|
||||
#endif
|
||||
#ifdef CONFIG_LIS2DW12_SLEEP
|
||||
/**
|
||||
* Trigger fires when channel reading transitions configured
|
||||
* thresholds for a certain time. The thresholds are configured
|
||||
* via the @ref SENSOR_ATTR_LOWER_THRESH and @ref SENSOR_ATTR_UPPER_THRESH
|
||||
* attributes.
|
||||
*/
|
||||
case SENSOR_TRIG_STATIONARY:
|
||||
LOG_DBG("Setting int2_sleep_chg: %d\n", enable);
|
||||
lis2dw12_pin_int2_route_get(ctx,
|
||||
&int_route.ctrl5_int2_pad_ctrl);
|
||||
int_route.ctrl5_int2_pad_ctrl.int2_sleep_chg = enable;
|
||||
return lis2dw12_pin_int2_route_set(ctx,
|
||||
&int_route.ctrl5_int2_pad_ctrl);
|
||||
#endif
|
||||
#ifdef CONFIG_LIS2DW12_FREEFALL
|
||||
/**
|
||||
* Trigger fires when the readings does not include Earth's
|
||||
|
@ -154,13 +169,22 @@ int lis2dw12_trigger_set(const struct device *dev,
|
|||
lis2dw12->double_tap_trig = trig;
|
||||
return lis2dw12_enable_int(dev, SENSOR_TRIG_DOUBLE_TAP, state);
|
||||
#endif /* CONFIG_LIS2DW12_TAP */
|
||||
#ifdef CONFIG_LIS2DW12_THRESHOLD
|
||||
case SENSOR_TRIG_THRESHOLD:
|
||||
#ifdef CONFIG_LIS2DW12_WAKEUP
|
||||
case SENSOR_TRIG_MOTION:
|
||||
{
|
||||
LOG_DBG("Set trigger %d (handler: %p)\n", trig->type, handler);
|
||||
lis2dw12->threshold_handler = handler;
|
||||
lis2dw12->threshold_trig = trig;
|
||||
return lis2dw12_enable_int(dev, SENSOR_TRIG_THRESHOLD, state);
|
||||
lis2dw12->motion_handler = handler;
|
||||
lis2dw12->motion_trig = trig;
|
||||
return lis2dw12_enable_int(dev, SENSOR_TRIG_MOTION, state);
|
||||
}
|
||||
#endif
|
||||
#ifdef CONFIG_LIS2DW12_SLEEP
|
||||
case SENSOR_TRIG_STATIONARY:
|
||||
{
|
||||
LOG_DBG("Set trigger %d (handler: %p)\n", trig->type, handler);
|
||||
lis2dw12->stationary_handler = handler;
|
||||
lis2dw12->stationary_trig = trig;
|
||||
return lis2dw12_enable_int(dev, SENSOR_TRIG_STATIONARY, state);
|
||||
}
|
||||
#endif
|
||||
#ifdef CONFIG_LIS2DW12_FREEFALL
|
||||
|
@ -214,14 +238,28 @@ static int lis2dw12_handle_double_tap_int(const struct device *dev)
|
|||
}
|
||||
#endif /* CONFIG_LIS2DW12_TAP */
|
||||
|
||||
#ifdef CONFIG_LIS2DW12_THRESHOLD
|
||||
#ifdef CONFIG_LIS2DW12_WAKEUP
|
||||
static int lis2dw12_handle_wu_ia_int(const struct device *dev)
|
||||
{
|
||||
struct lis2dw12_data *lis2dw12 = dev->data;
|
||||
sensor_trigger_handler_t handler = lis2dw12->threshold_handler;
|
||||
sensor_trigger_handler_t handler = lis2dw12->motion_handler;
|
||||
|
||||
if (handler) {
|
||||
handler(dev, lis2dw12->threshold_trig);
|
||||
handler(dev, lis2dw12->motion_trig);
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
#endif
|
||||
|
||||
#ifdef CONFIG_LIS2DW12_SLEEP
|
||||
static int lis2dw12_handle_sleep_change_int(const struct device *dev)
|
||||
{
|
||||
struct lis2dw12_data *lis2dw12 = dev->data;
|
||||
sensor_trigger_handler_t handler = lis2dw12->stationary_handler;
|
||||
|
||||
if (handler) {
|
||||
handler(dev, lis2dw12->stationary_trig);
|
||||
}
|
||||
|
||||
return 0;
|
||||
|
@ -265,11 +303,16 @@ static void lis2dw12_handle_interrupt(const struct device *dev)
|
|||
lis2dw12_handle_double_tap_int(dev);
|
||||
}
|
||||
#endif /* CONFIG_LIS2DW12_TAP */
|
||||
#ifdef CONFIG_LIS2DW12_THRESHOLD
|
||||
#ifdef CONFIG_LIS2DW12_WAKEUP
|
||||
if (sources.all_int_src.wu_ia) {
|
||||
lis2dw12_handle_wu_ia_int(dev);
|
||||
}
|
||||
#endif
|
||||
#ifdef CONFIG_LIS2DW12_SLEEP
|
||||
if (sources.all_int_src.sleep_change_ia) {
|
||||
lis2dw12_handle_sleep_change_int(dev);
|
||||
}
|
||||
#endif
|
||||
#ifdef CONFIG_LIS2DW12_FREEFALL
|
||||
if (sources.all_int_src.ff_ia) {
|
||||
lis2dw12_handle_ff_ia_int(dev);
|
||||
|
|
|
@ -247,3 +247,21 @@ properties:
|
|||
- 3 # LIS2DW12_DT_WAKEUP_4_ODR
|
||||
|
||||
enum: [0, 1, 2, 3]
|
||||
|
||||
sleep-duration:
|
||||
type: int
|
||||
default: 0
|
||||
description: |
|
||||
The sleep duration. Default value is the register reset value (0000 -> 16*1/ODR).
|
||||
If the accelerometer readings of the all axes are lower
|
||||
than the wakeup threshold value for the sleep duration long,
|
||||
then a sleep trigger occurs or the device goes in sleep mode. This value is 4 bits long in the
|
||||
register and 1 LSB = 512 * 1/ODR.
|
||||
|
||||
Value goes from 0 to 15
|
||||
|
||||
- 0 # LIS2DW12_DT_SLEEP_0_ODR
|
||||
...
|
||||
- 15 # LIS2DW12_DT_SLEEP_15_ODR
|
||||
|
||||
enum: [0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15]
|
||||
|
|
|
@ -39,4 +39,22 @@
|
|||
#define LIS2DW12_DT_WAKEUP_3_ODR 2
|
||||
#define LIS2DW12_DT_WAKEUP_4_ODR 3
|
||||
|
||||
/* sleep duration */
|
||||
#define LIS2DW12_DT_SLEEP_0_ODR 0
|
||||
#define LIS2DW12_DT_SLEEP_1_ODR 1
|
||||
#define LIS2DW12_DT_SLEEP_2_ODR 2
|
||||
#define LIS2DW12_DT_SLEEP_3_ODR 3
|
||||
#define LIS2DW12_DT_SLEEP_4_ODR 4
|
||||
#define LIS2DW12_DT_SLEEP_5_ODR 5
|
||||
#define LIS2DW12_DT_SLEEP_6_ODR 6
|
||||
#define LIS2DW12_DT_SLEEP_7_ODR 7
|
||||
#define LIS2DW12_DT_SLEEP_8_ODR 8
|
||||
#define LIS2DW12_DT_SLEEP_9_ODR 9
|
||||
#define LIS2DW12_DT_SLEEP_10_ODR 10
|
||||
#define LIS2DW12_DT_SLEEP_11_ODR 11
|
||||
#define LIS2DW12_DT_SLEEP_12_ODR 12
|
||||
#define LIS2DW12_DT_SLEEP_13_ODR 13
|
||||
#define LIS2DW12_DT_SLEEP_14_ODR 14
|
||||
#define LIS2DW12_DT_SLEEP_15_ODR 15
|
||||
|
||||
#endif /* ZEPHYR_INCLUDE_DT_BINDINGS_ST_LIS2DW12_H_ */
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue