You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@mynewt.apache.org by vi...@apache.org on 2018/04/11 20:24:30 UTC
[mynewt-core] branch master updated: WIP: Improvements to LIS2DW12
driver (#997)
This is an automated email from the ASF dual-hosted git repository.
vipulrahane pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/mynewt-core.git
The following commit(s) were added to refs/heads/master by this push:
new efe8d5f WIP: Improvements to LIS2DW12 driver (#997)
efe8d5f is described below
commit efe8d5f6bc0719b5a1cbb1d3537edafe2bd1c854
Author: matthewwarnes <36...@users.noreply.github.com>
AuthorDate: Wed Apr 11 21:24:27 2018 +0100
WIP: Improvements to LIS2DW12 driver (#997)
* improve lis2dw12 driver, add free fall event, configuration of ctrl3 and reduce devices access on stream read
* add new LIS2DW12 config to sensor_creator and FREEFALL event to sensor.h
---
.../sensors/lis2dw12/include/lis2dw12/lis2dw12.h | 102 ++++-
hw/drivers/sensors/lis2dw12/src/lis2dw12.c | 441 ++++++++++++++++++---
hw/drivers/sensors/lis2dw12/src/lis2dw12_priv.h | 6 +-
hw/drivers/sensors/lis2dw12/src/lis2dw12_shell.c | 8 +-
hw/sensor/creator/src/sensor_creator.c | 9 +
hw/sensor/include/sensor/sensor.h | 2 +
6 files changed, 501 insertions(+), 67 deletions(-)
diff --git a/hw/drivers/sensors/lis2dw12/include/lis2dw12/lis2dw12.h b/hw/drivers/sensors/lis2dw12/include/lis2dw12/lis2dw12.h
index d6241f8..f399255 100644
--- a/hw/drivers/sensors/lis2dw12/include/lis2dw12/lis2dw12.h
+++ b/hw/drivers/sensors/lis2dw12/include/lis2dw12/lis2dw12.h
@@ -32,6 +32,7 @@ extern "C" {
#define LIS2DW12_PM_LP_MODE3 0x02
#define LIS2DW12_PM_LP_MODE4 0x03
#define LIS2DW12_PM_HIGH_PERF 0x04
+#define LIS2DW12_PM_ON_DEMAND 0x08
#define LIS2DW12_DATA_RATE_0HZ 0x00
#define LIS2DW12_DATA_RATE_1_6HZ 0x10
@@ -182,12 +183,21 @@ struct lis2dw12_cfg {
struct lis2dw12_tap_settings tap_cfg;
uint8_t double_tap_event_enable;
+
+ uint8_t freefall_dur;
+ uint8_t freefall_ths;
uint8_t int1_pin_cfg;
uint8_t int2_pin_cfg;
bool map_int2_to_int1;
uint8_t int_enable;
+ uint8_t int_pp_od;
+ uint8_t int_latched;
+ uint8_t int_active;
+ uint8_t slp_mode;
+ uint8_t self_test_mode;
+
enum lis2dw12_fifo_mode fifo_mode;
uint8_t fifo_threshold;
@@ -350,7 +360,7 @@ int lis2dw12_get_power_mode(struct sensor_itf *itf, uint8_t *mode);
int lis2dw12_set_self_test(struct sensor_itf *itf, uint8_t mode);
/**
- * Gets the power mode of the sensor
+ * Gets the self test mode of the sensor
*
* @param The sensor interface
* @param ptr to self test mode read from sensor
@@ -360,6 +370,96 @@ int lis2dw12_set_self_test(struct sensor_itf *itf, uint8_t mode);
int lis2dw12_get_self_test(struct sensor_itf *itf, uint8_t *mode);
/**
+ * Sets the interrupt push-pull/open-drain selection
+ *
+ * @param The sensor interface
+ * @param interrupt setting (0 = push-pull, 1 = open-drain)
+ *
+ * @return 0 on success, non-zero on failure
+ */
+int lis2dw12_set_int_pp_od(struct sensor_itf *itf, uint8_t mode);
+
+/**
+ * Gets the interrupt push-pull/open-drain selection
+ *
+ * @param The sensor interface
+ * @param ptr to store setting (0 = push-pull, 1 = open-drain)
+ *
+ * @return 0 on success, non-zero on failure
+ */
+int lis2dw12_get_int_pp_od(struct sensor_itf *itf, uint8_t *mode);
+
+/**
+ * Sets whether latched interrupts are enabled
+ *
+ * @param The sensor interface
+ * @param value to set (0 = not latched, 1 = latched)
+ *
+ * @return 0 on success, non-zero on failure
+ */
+int lis2dw12_set_latched_int(struct sensor_itf *itf, uint8_t en);
+
+/**
+ * Gets whether latched interrupts are enabled
+ *
+ * @param The sensor interface
+ * @param ptr to store value (0 = not latched, 1 = latched)
+ *
+ * @return 0 on success, non-zero on failure
+ */
+int lis2dw12_get_latched_int(struct sensor_itf *itf, uint8_t *en);
+
+/**
+ * Sets whether interrupts are active high or low
+ *
+ * @param The sensor interface
+ * @param value to set (0 = active high, 1 = active low)
+ *
+ * @return 0 on success, non-zero on failure
+ */
+int lis2dw12_set_int_active(struct sensor_itf *itf, uint8_t low);
+
+/**
+ * Gets whether interrupts are active high or low
+ *
+ * @param The sensor interface
+ * @param ptr to store value (0 = active high, 1 = active low)
+ *
+ * @return 0 on success, non-zero on failure
+ */
+int lis2dw12_get_int_active(struct sensor_itf *itf, uint8_t *low);
+
+/**
+ * Sets single data conversion mode
+ *
+ * @param The sensor interface
+ * @param value to set (0 = trigger on INT2 pin, 1 = trigger on write to SLP_MODE_1)
+ *
+ * @return 0 on success, non-zero on failure
+ */
+int lis2dw12_set_slp_mode(struct sensor_itf *itf, uint8_t mode);
+
+/**
+ * Gets single data conversion mode
+ *
+ * @param The sensor interface
+ * @param ptr to store value (0 = trigger on INT2 pin, 1 = trigger on write to SLP_MODE_1)
+ *
+ * @return 0 on success, non-zero on failure
+ */
+int lis2dw12_get_slp_mode(struct sensor_itf *itf, uint8_t *mode);
+
+/**
+ * Starts a data conversion in on demand mode
+ *
+ * @param The sensor interface
+ *
+ * @return 0 on success, non-zero on failure
+ */
+int lis2dw12_start_on_demand_conversion(struct sensor_itf *itf);
+
+
+/**
* Set filter config
*
* @param the sensor interface
diff --git a/hw/drivers/sensors/lis2dw12/src/lis2dw12.c b/hw/drivers/sensors/lis2dw12/src/lis2dw12.c
index 85d253c..d2113a7 100644
--- a/hw/drivers/sensors/lis2dw12/src/lis2dw12.c
+++ b/hw/drivers/sensors/lis2dw12/src/lis2dw12.c
@@ -713,6 +713,229 @@ err:
}
/**
+ * Sets the interrupt push-pull/open-drain selection
+ *
+ * @param The sensor interface
+ * @param interrupt setting (0 = push-pull, 1 = open-drain)
+ *
+ * @return 0 on success, non-zero on failure
+ */
+int
+lis2dw12_set_int_pp_od(struct sensor_itf *itf, uint8_t mode)
+{
+ int rc;
+ uint8_t reg;
+
+ rc = lis2dw12_read8(itf, LIS2DW12_REG_CTRL_REG3, ®);
+ if (rc) {
+ return rc;
+ }
+
+ reg &= ~LIS2DW12_CTRL_REG3_PP_OD;
+ reg |= mode ? LIS2DW12_CTRL_REG3_PP_OD : 0;
+
+ return lis2dw12_write8(itf, LIS2DW12_REG_CTRL_REG3, reg);
+}
+
+/**
+ * Gets the interrupt push-pull/open-drain selection
+ *
+ * @param The sensor interface
+ * @param ptr to store setting (0 = push-pull, 1 = open-drain)
+ *
+ * @return 0 on success, non-zero on failure
+ */
+int
+lis2dw12_get_int_pp_od(struct sensor_itf *itf, uint8_t *mode)
+{
+ int rc;
+ uint8_t reg;
+
+ rc = lis2dw12_read8(itf, LIS2DW12_REG_CTRL_REG3, ®);
+ if (rc) {
+ return rc;
+ }
+
+ *mode = (reg & LIS2DW12_CTRL_REG3_PP_OD) ? 1 : 0;
+
+ return 0;
+}
+
+/**
+ * Sets whether latched interrupts are enabled
+ *
+ * @param The sensor interface
+ * @param value to set (0 = not latched, 1 = latched)
+ *
+ * @return 0 on success, non-zero on failure
+ */
+int
+lis2dw12_set_latched_int(struct sensor_itf *itf, uint8_t en)
+{
+ int rc;
+ uint8_t reg;
+
+ rc = lis2dw12_read8(itf, LIS2DW12_REG_CTRL_REG3, ®);
+ if (rc) {
+ return rc;
+ }
+
+ reg &= ~LIS2DW12_CTRL_REG3_LIR;
+ reg |= en ? LIS2DW12_CTRL_REG3_LIR : 0;
+
+ return lis2dw12_write8(itf, LIS2DW12_REG_CTRL_REG3, reg);
+
+}
+
+/**
+ * Gets whether latched interrupts are enabled
+ *
+ * @param The sensor interface
+ * @param ptr to store value (0 = not latched, 1 = latched)
+ *
+ * @return 0 on success, non-zero on failure
+ */
+int
+lis2dw12_get_latched_int(struct sensor_itf *itf, uint8_t *en)
+{
+ int rc;
+ uint8_t reg;
+
+ rc = lis2dw12_read8(itf, LIS2DW12_REG_CTRL_REG3, ®);
+ if (rc) {
+ return rc;
+ }
+
+ *en = (reg & LIS2DW12_CTRL_REG3_LIR) ? 1 : 0;
+
+ return 0;
+}
+
+/**
+ * Sets whether interrupts are active high or low
+ *
+ * @param The sensor interface
+ * @param value to set (0 = active high, 1 = active low)
+ *
+ * @return 0 on success, non-zero on failure
+ */
+int
+lis2dw12_set_int_active(struct sensor_itf *itf, uint8_t low)
+{
+ int rc;
+ uint8_t reg;
+
+ rc = lis2dw12_read8(itf, LIS2DW12_REG_CTRL_REG3, ®);
+ if (rc) {
+ return rc;
+ }
+
+ reg &= ~LIS2DW12_CTRL_REG3_H_LACTIVE;
+ reg |= low ? LIS2DW12_CTRL_REG3_H_LACTIVE : 0;
+
+ return lis2dw12_write8(itf, LIS2DW12_REG_CTRL_REG3, reg);
+
+}
+
+/**
+ * Gets whether interrupts are active high or low
+ *
+ * @param The sensor interface
+ * @param ptr to store value (0 = active high, 1 = active low)
+ *
+ * @return 0 on success, non-zero on failure
+ */
+int
+lis2dw12_get_int_active(struct sensor_itf *itf, uint8_t *low)
+{
+ int rc;
+ uint8_t reg;
+
+ rc = lis2dw12_read8(itf, LIS2DW12_REG_CTRL_REG3, ®);
+ if (rc) {
+ return rc;
+ }
+
+ *low = (reg & LIS2DW12_CTRL_REG3_H_LACTIVE) ? 1 : 0;
+
+ return 0;
+
+}
+
+/**
+ * Sets single data conversion mode
+ *
+ * @param The sensor interface
+ * @param value to set (0 = trigger on INT2 pin, 1 = trigger on write to SLP_MODE_1)
+ *
+ * @return 0 on success, non-zero on failure
+ */
+int
+lis2dw12_set_slp_mode(struct sensor_itf *itf, uint8_t mode)
+{
+ int rc;
+ uint8_t reg;
+
+ rc = lis2dw12_read8(itf, LIS2DW12_REG_CTRL_REG3, ®);
+ if (rc) {
+ return rc;
+ }
+
+ reg &= ~LIS2DW12_CTRL_REG3_SLP_MODE_SEL;
+ reg |= mode ? LIS2DW12_CTRL_REG3_SLP_MODE_SEL : 0;
+
+ return lis2dw12_write8(itf, LIS2DW12_REG_CTRL_REG3, reg);
+}
+
+/**
+ * Gets single data conversion mode
+ *
+ * @param The sensor interface
+ * @param ptr to store value (0 = trigger on INT2 pin, 1 = trigger on write to SLP_MODE_1)
+ *
+ * @return 0 on success, non-zero on failure
+ */
+int
+lis2dw12_get_slp_mode(struct sensor_itf *itf, uint8_t *mode)
+{
+ int rc;
+ uint8_t reg;
+
+ rc = lis2dw12_read8(itf, LIS2DW12_REG_CTRL_REG3, ®);
+ if (rc) {
+ return rc;
+ }
+
+ *mode = (reg & LIS2DW12_CTRL_REG3_SLP_MODE_SEL) ? 1 : 0;
+
+ return 0;
+}
+
+/**
+ * Starts a data conversion in on demand mode
+ *
+ * @param The sensor interface
+ *
+ * @return 0 on success, non-zero on failure
+ */
+int
+lis2dw12_start_on_demand_conversion(struct sensor_itf *itf)
+{
+ int rc;
+ uint8_t reg;
+
+ rc = lis2dw12_read8(itf, LIS2DW12_REG_CTRL_REG3, ®);
+ if (rc) {
+ return rc;
+ }
+
+ reg |= LIS2DW12_CTRL_REG3_SLP_MODE_1;
+
+ return lis2dw12_write8(itf, LIS2DW12_REG_CTRL_REG3, reg);
+}
+
+
+/**
* Set filter config
*
* @param the sensor interface
@@ -1002,13 +1225,27 @@ int lis2dw12_get_tap_cfg(struct sensor_itf *itf, struct lis2dw12_tap_settings *c
*/
int lis2dw12_set_freefall(struct sensor_itf *itf, uint8_t dur, uint8_t ths)
{
+ int rc;
uint8_t reg;
reg = 0;
reg |= (dur & 0x1F) << 3;
reg |= ths & LIS2DW12_FREEFALL_THS;
- return lis2dw12_write8(itf, LIS2DW12_REG_FREEFALL, reg);
+ rc = lis2dw12_write8(itf, LIS2DW12_REG_FREEFALL, reg);
+ if (rc) {
+ return rc;
+ }
+
+ rc = lis2dw12_read8(itf, LIS2DW12_REG_WAKE_UP_DUR, ®);
+ if (rc) {
+ return rc;
+ }
+
+ reg &= ~LIS2DW12_WAKE_DUR_FF_DUR;
+ reg |= dur & 0x20 ? LIS2DW12_WAKE_DUR_FF_DUR : 0;
+
+ return lis2dw12_write8(itf, LIS2DW12_REG_WAKE_UP_DUR, reg);
}
/**
@@ -1022,15 +1259,22 @@ int lis2dw12_set_freefall(struct sensor_itf *itf, uint8_t dur, uint8_t ths)
int lis2dw12_get_freefall(struct sensor_itf *itf, uint8_t *dur, uint8_t *ths)
{
int rc;
- uint8_t reg;
+ uint8_t ff_reg, wake_reg;
- rc = lis2dw12_read8(itf, LIS2DW12_REG_FREEFALL, ®);
+ rc = lis2dw12_read8(itf, LIS2DW12_REG_FREEFALL, &ff_reg);
if (rc) {
return rc;
}
- *dur = (reg & LIS2DW12_FREEFALL_DUR) >> 3;
- *ths = reg & LIS2DW12_FREEFALL_THS;
+ rc = lis2dw12_read8(itf, LIS2DW12_REG_WAKE_UP_DUR, &wake_reg);
+ if (rc) {
+ return rc;
+ }
+
+
+ *dur = (ff_reg & LIS2DW12_FREEFALL_DUR) >> 3;
+ *dur |= wake_reg & LIS2DW12_WAKE_DUR_FF_DUR ? (1 << 5) : 0;
+ *ths = wake_reg & LIS2DW12_FREEFALL_THS;
return 0;
}
@@ -1517,6 +1761,12 @@ int lis2dw12_run_self_test(struct sensor_itf *itf, int *result)
int16_t base[3], pos[3];
int i;
int16_t change;
+ uint8_t fs;
+
+ rc = lis2dw12_get_fs(itf, &fs);
+ if (rc) {
+ return rc;
+ }
/* ensure self test mode is disabled */
rc = lis2dw12_set_self_test(itf, LIS2DW12_ST_MODE_DISABLE);
@@ -1527,7 +1777,7 @@ int lis2dw12_run_self_test(struct sensor_itf *itf, int *result)
os_time_delay(OS_TICKS_PER_SEC / 10);
/* take base reading */
- rc = lis2dw12_get_data(itf, &(base[0]), &(base[1]), &(base[2]));
+ rc = lis2dw12_get_data(itf, fs, &(base[0]), &(base[1]), &(base[2]));
if (rc) {
return rc;
}
@@ -1541,7 +1791,7 @@ int lis2dw12_run_self_test(struct sensor_itf *itf, int *result)
os_time_delay(OS_TICKS_PER_SEC / 10);
/* take self test reading */
- rc = lis2dw12_get_data(itf, &(pos[0]), &(pos[1]), &(pos[2]));
+ rc = lis2dw12_get_data(itf, fs, &(pos[0]), &(pos[1]), &(pos[2]));
if (rc) {
return rc;
}
@@ -1774,6 +2024,31 @@ disable_interrupt(struct sensor * sensor, uint8_t int_to_disable)
return lis2dw12_set_int1_pin_cfg(itf, pdd->int_enable);
}
+int
+lis2dw12_get_fs(struct sensor_itf *itf, uint8_t *fs)
+{
+ int rc;
+
+ rc = lis2dw12_get_full_scale(itf, fs);
+ if (rc) {
+ return rc;
+ }
+
+ if (*fs == LIS2DW12_FS_2G) {
+ *fs = 2;
+ } else if (*fs == LIS2DW12_FS_4G) {
+ *fs = 4;
+ } else if (*fs == LIS2DW12_FS_8G) {
+ *fs = 8;
+ } else if (*fs == LIS2DW12_FS_16G) {
+ *fs = 16;
+ } else {
+ return SYS_EINVAL;
+ }
+
+ return 0;
+}
+
/**
* Gets a new data sample from the sensor.
*
@@ -1785,11 +2060,10 @@ disable_interrupt(struct sensor * sensor, uint8_t int_to_disable)
* @return 0 on success, non-zero on failure
*/
int
-lis2dw12_get_data(struct sensor_itf *itf, int16_t *x, int16_t *y, int16_t *z)
+lis2dw12_get_data(struct sensor_itf *itf, uint8_t fs, int16_t *x, int16_t *y, int16_t *z)
{
int rc;
uint8_t payload[6] = {0};
- uint8_t fs;
*x = *y = *z = 0;
@@ -1802,24 +2076,6 @@ lis2dw12_get_data(struct sensor_itf *itf, int16_t *x, int16_t *y, int16_t *z)
*y = payload[2] | (payload[3] << 8);
*z = payload[4] | (payload[5] << 8);
- rc = lis2dw12_get_full_scale(itf, &fs);
- if (rc) {
- goto err;
- }
-
- if (fs == LIS2DW12_FS_2G) {
- fs = 2;
- } else if (fs == LIS2DW12_FS_4G) {
- fs = 4;
- } else if (fs == LIS2DW12_FS_8G) {
- fs = 8;
- } else if (fs == LIS2DW12_FS_16G) {
- fs = 16;
- } else {
- rc = SYS_EINVAL;
- goto err;
- }
-
/*
* Since full scale is +/-(fs)g,
* fs should be multiplied by 2 to account for full scale.
@@ -1837,7 +2093,7 @@ err:
}
static int lis2dw12_do_read(struct sensor *sensor, sensor_data_func_t data_func,
- void * data_arg)
+ void * data_arg, uint8_t fs)
{
struct sensor_accel_data sad;
struct sensor_itf *itf;
@@ -1849,7 +2105,7 @@ static int lis2dw12_do_read(struct sensor *sensor, sensor_data_func_t data_func,
x = y = z = 0;
- rc = lis2dw12_get_data(itf, &x, &y, &z);
+ rc = lis2dw12_get_data(itf, fs, &x, &y, &z);
if (rc) {
goto err;
}
@@ -1894,12 +2150,23 @@ lis2dw12_poll_read(struct sensor * sensor, sensor_type_t sensor_type,
sensor_data_func_t data_func, void * data_arg,
uint32_t timeout)
{
+ int rc;
+ struct sensor_itf *itf;
+ uint8_t fs;
+
+ itf = SENSOR_GET_ITF(sensor);
+
/* If the read isn't looking for accel data, don't do anything. */
if (!(sensor_type & SENSOR_TYPE_ACCELEROMETER)) {
return SYS_EINVAL;
}
- return lis2dw12_do_read(sensor, data_func, data_arg);
+ rc = lis2dw12_get_fs(itf, &fs);
+ if (rc) {
+ return rc;
+ }
+
+ return lis2dw12_do_read(sensor, data_func, data_arg, fs);
}
int
@@ -1916,6 +2183,7 @@ lis2dw12_stream_read(struct sensor *sensor,
os_time_t stop_ticks = 0;
struct lis2dw12_private_driver_data *pdd;
uint8_t fifo_samples;
+ uint8_t fs;
/* If the read isn't looking for accel data, don't do anything. */
if (!(sensor_type & SENSOR_TYPE_ACCELEROMETER)) {
@@ -1948,25 +2216,42 @@ lis2dw12_stream_read(struct sensor *sensor,
stop_ticks = os_time_get() + time_ticks;
}
+
+ rc = lis2dw12_get_fs(itf, &fs);
+ if (rc) {
+ goto done;
+ }
+
for (;;) {
wait_interrupt(&lis2dw12->intr, pdd->int_num);
+
+ /* force at least one read for cases when fifo is disabled */
fifo_samples = 1;
while(fifo_samples > 0) {
- rc = lis2dw12_do_read(sensor, read_func, read_arg);
- if (rc) {
- goto done;
+
+ /* read all data we beleive is currently in fifo */
+ while(fifo_samples > 0) {
+ rc = lis2dw12_do_read(sensor, read_func, read_arg, fs);
+ if (rc) {
+ goto done;
+ }
+ fifo_samples--;
+
}
+ /* check if any data is available in fifo */
rc = lis2dw12_get_fifo_samples(itf, &fifo_samples);
if (rc) {
goto done;
}
+
}
-
+
if (time_ms != 0 && OS_TIME_TICK_GT(os_time_get(), stop_ticks)) {
- break;
+ break;
}
+
}
done:
@@ -2037,14 +2322,17 @@ lis2dw12_sensor_set_notification(struct sensor *sensor, sensor_event_type_t type
struct lis2dw12_private_driver_data *pdd;
int rc;
- if ((type & ~(SENSOR_EVENT_TYPE_DOUBLE_TAP |
- SENSOR_EVENT_TYPE_SINGLE_TAP)) != 0) {
- return SYS_EINVAL;
+ if(type == SENSOR_EVENT_TYPE_DOUBLE_TAP) {
+ int_cfg |= LIS2DW12_INT1_CFG_DOUBLE_TAP;
}
-
- /*XXX for now we do not support registering for both events */
- if (type == (SENSOR_EVENT_TYPE_DOUBLE_TAP |
- SENSOR_EVENT_TYPE_SINGLE_TAP)) {
+ else if(type == SENSOR_EVENT_TYPE_SINGLE_TAP) {
+ int_cfg |= LIS2DW12_INT1_CFG_SINGLE_TAP;
+ }
+ else if(type == SENSOR_EVENT_TYPE_FREE_FALL) {
+ int_cfg |= LIS2DW12_INT1_CFG_FF;
+ } else {
+ /* here if type is set to no valid event or more than one event */
+ /* we do not currently support registering for more than one event */
return SYS_EINVAL;
}
@@ -2055,15 +2343,7 @@ lis2dw12_sensor_set_notification(struct sensor *sensor, sensor_event_type_t type
if (pdd->registered_mask & LIS2DW12_NOTIFY_MASK) {
return SYS_EBUSY;
}
-
- /* Enable tap interrupt */
- if(type == SENSOR_EVENT_TYPE_DOUBLE_TAP) {
- int_cfg |= LIS2DW12_INT1_CFG_DOUBLE_TAP;
- }
- if(type == SENSOR_EVENT_TYPE_SINGLE_TAP) {
- int_cfg |= LIS2DW12_INT1_CFG_SINGLE_TAP;
- }
-
+
rc = enable_interrupt(sensor, int_cfg);
if (rc) {
return rc;
@@ -2099,18 +2379,22 @@ lis2dw12_sensor_unset_notification(struct sensor *sensor, sensor_event_type_t ty
struct lis2dw12 * lis2dw12;
struct sensor_itf *itf;
int rc;
+ uint8_t int_cfg = 0;
- if ((type & ~(SENSOR_EVENT_TYPE_DOUBLE_TAP |
- SENSOR_EVENT_TYPE_SINGLE_TAP)) != 0) {
- return SYS_EINVAL;
+ if(type == SENSOR_EVENT_TYPE_DOUBLE_TAP) {
+ int_cfg |= LIS2DW12_INT1_CFG_DOUBLE_TAP;
}
-
- /*XXX for now we do not support registering for both events */
- if (type == (SENSOR_EVENT_TYPE_DOUBLE_TAP |
- SENSOR_EVENT_TYPE_SINGLE_TAP)) {
+ else if(type == SENSOR_EVENT_TYPE_SINGLE_TAP) {
+ int_cfg |= LIS2DW12_INT1_CFG_SINGLE_TAP;
+ }
+ else if(type == SENSOR_EVENT_TYPE_FREE_FALL) {
+ int_cfg |= LIS2DW12_INT1_CFG_FF;
+ } else {
+ /* here if type is set to no valid event or more than one event */
+ /* we do not currently support registering for more than one event */
return SYS_EINVAL;
}
-
+
lis2dw12 = (struct lis2dw12 *)SENSOR_GET_DEVICE(sensor);
itf = SENSOR_GET_ITF(sensor);
@@ -2122,7 +2406,7 @@ lis2dw12_sensor_unset_notification(struct sensor *sensor, sensor_event_type_t ty
return rc;
}
- return disable_interrupt(sensor, 0);
+ return disable_interrupt(sensor, int_cfg);
}
static int
@@ -2148,7 +2432,8 @@ lis2dw12_sensor_handle_interrupt(struct sensor * sensor)
if ((pdd->registered_mask & LIS2DW12_NOTIFY_MASK) &&
((int_src & LIS2DW12_INT_SRC_STAP) ||
- (int_src & LIS2DW12_INT_SRC_DTAP))) {
+ (int_src & LIS2DW12_INT_SRC_DTAP) ||
+ (int_src & LIS2DW12_INT_SRC_FF_IA))) {
sensor_mgr_put_notify_evt(&pdd->notify_ctx);
}
@@ -2331,10 +2616,30 @@ lis2dw12_config(struct lis2dw12 *lis2dw12, struct lis2dw12_cfg *cfg)
goto err;
}
- rc = lis2dw12_write8(itf, LIS2DW12_REG_CTRL_REG3, LIS2DW12_CTRL_REG3_LIR);
+ rc = lis2dw12_set_int_pp_od(itf, cfg->int_pp_od);
if (rc) {
goto err;
}
+ lis2dw12->cfg.int_pp_od = cfg->int_pp_od;
+
+ rc = lis2dw12_set_latched_int(itf, cfg->int_latched);
+ if (rc) {
+ goto err;
+ }
+ lis2dw12->cfg.int_latched = cfg->int_latched;
+
+ rc = lis2dw12_set_int_active(itf, cfg->int_active);
+ if (rc) {
+ goto err;
+ }
+ lis2dw12->cfg.int_active = cfg->int_active;
+
+ rc = lis2dw12_set_slp_mode(itf, cfg->slp_mode);
+ if (rc) {
+ goto err;
+ }
+ lis2dw12->cfg.slp_mode = cfg->slp_mode;
+
rc = lis2dw12_set_offsets(itf, cfg->offset_x, cfg->offset_y, cfg->offset_z,
cfg->offset_weight);
@@ -2376,10 +2681,11 @@ lis2dw12_config(struct lis2dw12 *lis2dw12, struct lis2dw12_cfg *cfg)
lis2dw12->cfg.rate = cfg->rate;
- rc = lis2dw12_set_self_test(itf, LIS2DW12_ST_MODE_DISABLE);
+ rc = lis2dw12_set_self_test(itf, cfg->self_test_mode);
if (rc) {
goto err;
}
+ lis2dw12->cfg.self_test_mode = cfg->self_test_mode;
rc = lis2dw12_set_power_mode(itf, cfg->power_mode);
if (rc) {
@@ -2439,6 +2745,15 @@ lis2dw12_config(struct lis2dw12 *lis2dw12, struct lis2dw12_cfg *cfg)
}
lis2dw12->cfg.double_tap_event_enable = cfg->double_tap_event_enable;
+ rc = lis2dw12_set_freefall(itf, cfg->freefall_dur, cfg->freefall_ths);
+ if (rc) {
+ goto err;
+ }
+
+ lis2dw12->cfg.freefall_dur = cfg->freefall_dur;
+ lis2dw12->cfg.freefall_ths = cfg->freefall_ths;
+
+
rc = lis2dw12_set_int_enable(itf, cfg->int_enable);
if (rc) {
goto err;
diff --git a/hw/drivers/sensors/lis2dw12/src/lis2dw12_priv.h b/hw/drivers/sensors/lis2dw12/src/lis2dw12_priv.h
index 95760a0..795a16a 100644
--- a/hw/drivers/sensors/lis2dw12/src/lis2dw12_priv.h
+++ b/hw/drivers/sensors/lis2dw12/src/lis2dw12_priv.h
@@ -50,7 +50,8 @@ extern "C" {
#define LIS2DW12_CTRL_REG3_PP_OD (1 << 5)
#define LIS2DW12_CTRL_REG3_LIR (1 << 4)
#define LIS2DW12_CTRL_REG3_H_LACTIVE (1 << 3)
-#define LIS2DW12_CTRL_REG3_SLP_MODE (0x3 << 0)
+#define LIS2DW12_CTRL_REG3_SLP_MODE_SEL (1 << 1)
+#define LIS2DW12_CTRL_REG3_SLP_MODE_1 (1 << 0)
#define LIS2DW12_REG_CTRL_REG4 0x23
@@ -162,8 +163,9 @@ int lis2dw12_readlen(struct sensor_itf *itf, uint8_t reg, uint8_t *buffer, uint8
void lis2dw12_calc_acc_ms2(int16_t raw_acc, float *facc);
void lis2dw12_calc_acc_mg(float acc_ms2, int16_t *acc_mg);
-int lis2dw12_get_data(struct sensor_itf *itf, int16_t *x, int16_t *y, int16_t *z);
+int lis2dw12_get_data(struct sensor_itf *itf, uint8_t fs, int16_t *x, int16_t *y, int16_t *z);
+int lis2dw12_get_fs(struct sensor_itf *itf, uint8_t *fs);
#ifdef __cplusplus
}
diff --git a/hw/drivers/sensors/lis2dw12/src/lis2dw12_shell.c b/hw/drivers/sensors/lis2dw12/src/lis2dw12_shell.c
index 3ebe98c..66bfdc0 100644
--- a/hw/drivers/sensors/lis2dw12/src/lis2dw12_shell.c
+++ b/hw/drivers/sensors/lis2dw12/src/lis2dw12_shell.c
@@ -120,6 +120,7 @@ lis2dw12_shell_cmd_read(int argc, char **argv)
char tmpstr[13];
int16_t x,y,z;
float fx,fy,fz;
+ uint8_t fs;
if (argc > 3) {
return lis2dw12_shell_err_too_many_args(argv[1]);
@@ -136,7 +137,12 @@ lis2dw12_shell_cmd_read(int argc, char **argv)
while(samples--) {
- rc = lis2dw12_get_data(&g_sensor_itf, &x, &y, &z);
+ rc = lis2dw12_get_fs(&g_sensor_itf, &fs);
+ if (rc) {
+ return rc;
+ }
+
+ rc = lis2dw12_get_data(&g_sensor_itf, fs,&x, &y, &z);
if (rc) {
console_printf("Read failed: %d\n", rc);
return rc;
diff --git a/hw/sensor/creator/src/sensor_creator.c b/hw/sensor/creator/src/sensor_creator.c
index 3c7b0f3..69df71c 100644
--- a/hw/sensor/creator/src/sensor_creator.c
+++ b/hw/sensor/creator/src/sensor_creator.c
@@ -770,11 +770,20 @@ config_lis2dw12_sensor(void)
cfg.tap_cfg.quiet = 0; /* 10ms */
cfg.tap_cfg.shock = 3; /* 120ms */
cfg.double_tap_event_enable = 0;
+
+ cfg.freefall_dur = 6;
+ cfg.freefall_ths = 3; /* ~312mg */
cfg.int1_pin_cfg = 0;
cfg.int2_pin_cfg = 0;
cfg.int_enable = 0;
+ cfg.int_pp_od = 0;
+ cfg.int_latched = 0;
+ cfg.int_active = 0;
+ cfg.slp_mode = 0;
+ cfg.self_test_mode = LIS2DW12_ST_MODE_DISABLE;
+
cfg.fifo_mode = LIS2DW12_FIFO_M_BYPASS;
cfg.fifo_threshold = 32;
cfg.stream_read_interrupt = LIS2DW12_INT1_CFG_DRDY;
diff --git a/hw/sensor/include/sensor/sensor.h b/hw/sensor/include/sensor/sensor.h
index 7bb2b64..c78839e 100644
--- a/hw/sensor/include/sensor/sensor.h
+++ b/hw/sensor/include/sensor/sensor.h
@@ -102,6 +102,8 @@ typedef enum {
SENSOR_EVENT_TYPE_DOUBLE_TAP = (1 << 0),
/* Accelerometer single tap event */
SENSOR_EVENT_TYPE_SINGLE_TAP = (1 << 1),
+ /* Accelerometer free fall event */
+ SENSOR_EVENT_TYPE_FREE_FALL = (1 << 2)
} sensor_event_type_t;
--
To stop receiving notification emails like this one, please contact
vipulrahane@apache.org.