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 7d2b35d [DO NOT MERGE] Support for one shot polling mode (#1637) 7d2b35d is described below commit 7d2b35d23f9d2b22529b26cd071abd7db7d370c6 Author: reshtitus <43156600+reshti...@users.noreply.github.com> AuthorDate: Fri Feb 8 18:17:09 2019 -0800 [DO NOT MERGE] Support for one shot polling mode (#1637) * Changes to lps33hw and lps33thw drivers for supporting ONE SHOT mode to save power - For user defined function `sensor_read_ctx` lives on the stack, this variable needs to propagate to the lowest level of indirection, which is the callout callback. Hence, a copy of it is needed while storing the data_func and data_arg in the driver structure. - Making changes as per reviews, adding comments and cleaning up. - Moving `sensor_read_ctx` to `sensor.h` - One shot mode is optionally compilable and is only operational when the data rate is < 75Hz. For 75Hz, one shot mode is not used. --- .../sensors/lps33hw/include/lps33hw/lps33hw.h | 8 +- hw/drivers/sensors/lps33hw/src/lps33hw.c | 97 +++++++++++++++++++--- hw/drivers/sensors/lps33hw/syscfg.yml | 3 + .../sensors/lps33thw/include/lps33thw/lps33thw.h | 8 +- hw/drivers/sensors/lps33thw/src/lps33thw.c | 96 ++++++++++++++++++--- hw/drivers/sensors/lps33thw/syscfg.yml | 3 + hw/sensor/include/sensor/sensor.h | 8 ++ hw/sensor/src/sensor.c | 5 -- 8 files changed, 194 insertions(+), 34 deletions(-) diff --git a/hw/drivers/sensors/lps33hw/include/lps33hw/lps33hw.h b/hw/drivers/sensors/lps33hw/include/lps33hw/lps33hw.h index 22f6e4b..cc3e102 100644 --- a/hw/drivers/sensors/lps33hw/include/lps33hw/lps33hw.h +++ b/hw/drivers/sensors/lps33hw/include/lps33hw/lps33hw.h @@ -75,8 +75,7 @@ struct lps33hw_cfg { }; struct lps33hw_private_driver_data { - sensor_data_func_t user_handler; - void *user_arg; + struct sensor_read_ctx user_ctx; }; struct lps33hw { @@ -95,6 +94,11 @@ struct lps33hw { #if MYNEWT_VAL(BUS_DRIVER_PRESENT) bool node_is_spi; #endif +#if MYNEWT_VAL(LPS33HW_ONE_SHOT_MODE) + sensor_type_t type; + sensor_data_func_t data_func; + struct os_callout lps33hw_one_shot_read; +#endif }; /** diff --git a/hw/drivers/sensors/lps33hw/src/lps33hw.c b/hw/drivers/sensors/lps33hw/src/lps33hw.c index b54527b..c7585f0 100644 --- a/hw/drivers/sensors/lps33hw/src/lps33hw.c +++ b/hw/drivers/sensors/lps33hw/src/lps33hw.c @@ -85,6 +85,13 @@ static int lps33hw_sensor_clear_low_thresh(struct sensor *sensor, static int lps33hw_sensor_clear_high_thresh(struct sensor *sensor, sensor_type_t type); +static void lps33hw_read_interrupt_handler(void *arg); + +#if MYNEWT_VAL(LPS33HW_ONE_SHOT_MODE) +#define LPS33HW_ONE_SHOT_TICKS 2 +static void lps33hw_one_shot_read_cb(struct os_event *ev); +#endif + static const struct sensor_driver g_lps33hw_sensor_driver = { .sd_read = lps33hw_sensor_read, .sd_get_config = lps33hw_sensor_get_config, @@ -96,6 +103,48 @@ static const struct sensor_driver g_lps33hw_sensor_driver = { }; /* + * Sensor read after ONE_SHOT conversion + */ +#if MYNEWT_VAL(LPS33HW_ONE_SHOT_MODE) +static void lps33hw_one_shot_read_cb(struct os_event *ev) +{ + int rc; + struct lps33hw *lps33hw; + struct sensor *sensor; + lps33hw = (struct lps33hw *)ev->ev_arg; + sensor = &lps33hw->sensor; + struct sensor_itf *itf; + itf = SENSOR_GET_ITF(sensor); + + if (lps33hw->type & SENSOR_TYPE_PRESSURE) { + if (lps33hw->cfg.int_cfg.data_rdy) { + /* Stream read */ + rc = lps33hw_enable_interrupt(sensor, + lps33hw_read_interrupt_handler, sensor); + } else { + /* Read once */ + struct sensor_press_data spd; + rc = lps33hw_get_pressure(itf, &spd.spd_press); + if (!rc) { + spd.spd_press_is_valid = 1; + rc = lps33hw->data_func(sensor, &lps33hw->pdd.user_ctx, &spd, + SENSOR_TYPE_PRESSURE); + } + } + } + if (lps33hw->type & SENSOR_TYPE_TEMPERATURE) { + struct sensor_temp_data std; + rc = lps33hw_get_temperature(itf, &std.std_temp); + if (!rc) { + std.std_temp_is_valid = 1; + rc = lps33hw->data_func(sensor, &lps33hw->pdd.user_ctx, &std, + SENSOR_TYPE_TEMPERATURE); + } + } +} +#endif + +/* * Converts pressure value in pascals to a value found in the pressure * threshold register of the device. * @@ -883,6 +932,9 @@ lps33hw_init(struct os_dev *dev, void *arg) } lps = (struct lps33hw *) dev; +#if MYNEWT_VAL(LPS33HW_ONE_SHOT_MODE) + os_callout_init(&lps->lps33hw_one_shot_read, os_eventq_dflt_get(), lps33hw_one_shot_read_cb, dev); +#endif sensor = &lps->sensor; lps->cfg.mask = SENSOR_TYPE_ALL; @@ -1016,7 +1068,7 @@ lps33hw_read_interrupt_handler(void *arg) spd.spd_press_is_valid = 0; } else { spd.spd_press_is_valid = 1; - lps33hw->pdd.user_handler(sensor, lps33hw->pdd.user_arg, + lps33hw->pdd.user_ctx.user_func(sensor, lps33hw->pdd.user_ctx.user_arg, &spd, SENSOR_TYPE_PRESSURE); } } @@ -1025,29 +1077,48 @@ static int lps33hw_sensor_read(struct sensor *sensor, sensor_type_t type, sensor_data_func_t data_func, void *data_arg, uint32_t timeout) { - (void)timeout; int rc = SYS_EINVAL; struct sensor_itf *itf; - itf = SENSOR_GET_ITF(sensor); - if (type & SENSOR_TYPE_PRESSURE) { - struct lps33hw *lps33hw; + uint8_t rate; + rc = lps33hw_get_value(itf, LPS33HW_CTRL_REG1_ODR, &rate); + if (rc) { + return rc; + } + struct lps33hw *lps33hw; + lps33hw = (struct lps33hw *)SENSOR_GET_DEVICE(sensor); + (void)timeout; - lps33hw = (struct lps33hw *)SENSOR_GET_DEVICE(sensor); +#if MYNEWT_VAL(LPS33HW_ONE_SHOT_MODE) + if (rate != LPS33HW_75HZ) { + lps33hw->data_func = data_func; + lps33hw->pdd.user_ctx = *(struct sensor_read_ctx *)data_arg; + lps33hw->type = type; + rc = lps33hw_set_value(itf, LPS33HW_CTRL_REG1_ODR, LPS33HW_ONE_SHOT); + if (rc) { + return rc; + } + rc = lps33hw_set_value(itf, LPS33HW_CTRL_REG2_ONE_SHOT, 0x01); + if (rc) { + return rc; + } + os_callout_reset(&lps33hw->lps33hw_one_shot_read, LPS33HW_ONE_SHOT_TICKS); + return rc; + } +#endif + if (type & SENSOR_TYPE_PRESSURE) { if (lps33hw->cfg.int_cfg.data_rdy) { /* Stream read */ - lps33hw->pdd.user_handler = data_func; - lps33hw->pdd.user_arg = data_arg; - + lps33hw->pdd.user_ctx.user_func = data_func; + lps33hw->pdd.user_ctx.user_arg = data_arg; rc = lps33hw_enable_interrupt(sensor, - lps33hw_read_interrupt_handler, sensor); + lps33hw_read_interrupt_handler, sensor); if (rc) { return rc; } } else { /* Read once */ struct sensor_press_data spd; - rc = lps33hw_get_pressure(itf, &spd.spd_press); if (rc) { return rc; @@ -1065,19 +1136,19 @@ lps33hw_sensor_read(struct sensor *sensor, sensor_type_t type, if (rc) { return rc; } - std.std_temp_is_valid = 1; rc = data_func(sensor, data_arg, &std, SENSOR_TYPE_TEMPERATURE); } if (!(type & SENSOR_TYPE_TEMPERATURE) && !(type & SENSOR_TYPE_PRESSURE)) { - return SYS_EINVAL; + return SYS_EINVAL; } return rc; } + static int lps33hw_sensor_set_config(struct sensor *sensor, void *cfg) { diff --git a/hw/drivers/sensors/lps33hw/syscfg.yml b/hw/drivers/sensors/lps33hw/syscfg.yml index 12f5a63..5c344b2 100644 --- a/hw/drivers/sensors/lps33hw/syscfg.yml +++ b/hw/drivers/sensors/lps33hw/syscfg.yml @@ -47,4 +47,7 @@ syscfg.defs: description: > Number of OS ticks to wait for each I2C transaction to complete. value: 3 + LPS33HW_ONE_SHOT_MODE: + description: 'Enables one shot mode on the sensor' + value: 0 \ No newline at end of file diff --git a/hw/drivers/sensors/lps33thw/include/lps33thw/lps33thw.h b/hw/drivers/sensors/lps33thw/include/lps33thw/lps33thw.h index 3d3f760..89f1a5a 100644 --- a/hw/drivers/sensors/lps33thw/include/lps33thw/lps33thw.h +++ b/hw/drivers/sensors/lps33thw/include/lps33thw/lps33thw.h @@ -79,8 +79,7 @@ struct lps33thw_cfg { }; struct lps33thw_private_driver_data { - sensor_data_func_t user_handler; - void *user_arg; + struct sensor_read_ctx user_ctx; }; struct lps33thw { @@ -96,6 +95,11 @@ struct lps33thw { #if MYNEWT_VAL(BUS_DRIVER_PRESENT) bool node_is_spi; #endif +#if MYNEWT_VAL(LPS33THW_ONE_SHOT_MODE) + sensor_type_t type; + sensor_data_func_t data_func; + struct os_callout lps33thw_one_shot_read; +#endif }; /** diff --git a/hw/drivers/sensors/lps33thw/src/lps33thw.c b/hw/drivers/sensors/lps33thw/src/lps33thw.c index d3d44cb..eaaa1ee 100644 --- a/hw/drivers/sensors/lps33thw/src/lps33thw.c +++ b/hw/drivers/sensors/lps33thw/src/lps33thw.c @@ -85,6 +85,12 @@ static int lps33thw_sensor_clear_low_thresh(struct sensor *sensor, sensor_type_t type); static int lps33thw_sensor_clear_high_thresh(struct sensor *sensor, sensor_type_t type); +static void lps33thw_read_interrupt_handler(void *arg); + +#if MYNEWT_VAL(LPS33THW_ONE_SHOT_MODE) +#define LPS33THW_ONE_SHOT_TICKS 2 +static void lps33thw_one_shot_read_cb(struct os_event *ev); +#endif static const struct sensor_driver g_lps33thw_sensor_driver = { .sd_read = lps33thw_sensor_read, @@ -97,6 +103,48 @@ static const struct sensor_driver g_lps33thw_sensor_driver = { }; /* + * Sensor read after ONE_SHOT conversion + */ +#if MYNEWT_VAL(LPS33THW_ONE_SHOT_MODE) +static void lps33thw_one_shot_read_cb(struct os_event *ev) +{ + int rc; + struct lps33thw *lps33thw; + struct sensor *sensor; + lps33thw = (struct lps33thw *)ev->ev_arg; + sensor = &lps33thw->sensor; + struct sensor_itf *itf; + itf = SENSOR_GET_ITF(sensor); + + if (lps33thw->type & SENSOR_TYPE_PRESSURE) { + if (lps33thw->cfg.int_cfg.data_rdy) { + /* Stream read */ + rc = lps33thw_enable_interrupt(sensor, + lps33thw_read_interrupt_handler, sensor); + } else { + /* Read once */ + struct sensor_press_data spd; + + rc = lps33thw_get_pressure(itf, &spd.spd_press); + if (!rc) { + spd.spd_press_is_valid = 1; + rc = lps33thw->data_func(sensor, &lps33thw->pdd.user_ctx, &spd, SENSOR_TYPE_PRESSURE); + } + } + } + if (lps33thw->type & SENSOR_TYPE_TEMPERATURE) { + struct sensor_temp_data std; + + rc = lps33thw_get_temperature(itf, &std.std_temp); + if(!rc){ + std.std_temp_is_valid = 1; + rc = lps33thw->data_func(sensor, &lps33thw->pdd.user_ctx, &std, + SENSOR_TYPE_TEMPERATURE); + } + } +} +#endif +/* * Converts pressure value in pascals to a value found in the pressure * threshold register of the device. * @@ -886,6 +934,9 @@ lps33thw_init(struct os_dev *dev, void *arg) } lps = (struct lps33thw *) dev; +#if MYNEWT_VAL(LPS33THW_ONE_SHOT_MODE) + os_callout_init(&lps->lps33thw_one_shot_read, os_eventq_dflt_get(), lps33thw_one_shot_read_cb, dev); +#endif sensor = &lps->sensor; lps->cfg.mask = SENSOR_TYPE_ALL; @@ -1024,7 +1075,7 @@ lps33thw_read_interrupt_handler(void *arg) spd.spd_press_is_valid = 0; } else { spd.spd_press_is_valid = 1; - lps33thw->pdd.user_handler(sensor, lps33thw->pdd.user_arg, + lps33thw->pdd.user_ctx.user_func(sensor, lps33thw->pdd.user_ctx.user_arg, &spd, SENSOR_TYPE_PRESSURE); } } @@ -1033,29 +1084,51 @@ static int lps33thw_sensor_read(struct sensor *sensor, sensor_type_t type, sensor_data_func_t data_func, void *data_arg, uint32_t timeout) { - (void)timeout; int rc = SYS_EINVAL; struct sensor_itf *itf; - itf = SENSOR_GET_ITF(sensor); + uint8_t rate; + rc = lps33thw_get_value(itf, LPS33THW_CTRL_REG1_ODR, &rate); + if (rc) { + return rc; + } + struct lps33thw *lps33thw; + lps33thw = (struct lps33thw *)SENSOR_GET_DEVICE(sensor); + (void)timeout; + +#if MYNEWT_VAL(LPS33THW_ONE_SHOT_MODE) + if (rate != LPS33THW_75HZ) { + lps33thw->data_func = data_func; + lps33thw->pdd.user_ctx = *(struct sensor_read_ctx *)data_arg; + lps33thw->type = type; + rc = lps33thw_set_value(itf, LPS33THW_CTRL_REG1_ODR, LPS33THW_ONE_SHOT); + if (rc) { + return rc; + } + rc = lps33thw_set_value(itf, LPS33THW_CTRL_REG2_ONE_SHOT, 0x01); + if (rc) { + return rc; + } + os_callout_reset(&lps33thw->lps33thw_one_shot_read, LPS33THW_ONE_SHOT_TICKS); + return rc; + } +#endif + if (type & SENSOR_TYPE_PRESSURE) { struct lps33thw *lps33thw; - lps33thw = (struct lps33thw *)SENSOR_GET_DEVICE(sensor); if (lps33thw->cfg.int_cfg.data_rdy) { /* Stream read */ - lps33thw->pdd.user_handler = data_func; - lps33thw->pdd.user_arg = data_arg; - + lps33thw->pdd.user_ctx.user_func = data_func; + lps33thw->pdd.user_ctx.user_arg = data_arg; rc = lps33thw_enable_interrupt(sensor, - lps33thw_read_interrupt_handler, sensor); + lps33thw_read_interrupt_handler, sensor); if (rc) { return rc; } } else { /* Read once */ struct sensor_press_data spd; - rc = lps33thw_get_pressure(itf, &spd.spd_press); if (rc) { return rc; @@ -1073,14 +1146,13 @@ lps33thw_sensor_read(struct sensor *sensor, sensor_type_t type, if (rc) { return rc; } - std.std_temp_is_valid = 1; rc = data_func(sensor, data_arg, &std, SENSOR_TYPE_TEMPERATURE); } - if (!(type & SENSOR_TYPE_PRESSURE) && !(type & SENSOR_TYPE_TEMPERATURE)) { - return SYS_EINVAL; + if (!(type & SENSOR_TYPE_TEMPERATURE) && !(type & SENSOR_TYPE_PRESSURE)) { + return SYS_EINVAL; } return rc; diff --git a/hw/drivers/sensors/lps33thw/syscfg.yml b/hw/drivers/sensors/lps33thw/syscfg.yml index b10819c..d4577fb 100644 --- a/hw/drivers/sensors/lps33thw/syscfg.yml +++ b/hw/drivers/sensors/lps33thw/syscfg.yml @@ -35,6 +35,9 @@ syscfg.defs: description: > Number of OS ticks to wait for each I2C transaction to complete. value: 3 + LPS33THW_ONE_SHOT_MODE: + description: 'Enables one shot mode on the sensor' + value: 0 syscfg.defs.!BUS_DRIVER_PRESENT: LPS33THW_SHELL_ITF_NUM: diff --git a/hw/sensor/include/sensor/sensor.h b/hw/sensor/include/sensor/sensor.h index 5eeb7e8..8828756 100644 --- a/hw/sensor/include/sensor/sensor.h +++ b/hw/sensor/include/sensor/sensor.h @@ -628,6 +628,14 @@ struct sensor { }; /** + * Read context for calling user function with argument + */ +struct sensor_read_ctx { + sensor_data_func_t user_func; + void *user_arg; +}; + +/** * Lock access to the sensor_itf specified by si. Blocks until lock acquired. * * @param si The sensor_itf to lock diff --git a/hw/sensor/src/sensor.c b/hw/sensor/src/sensor.c index 1e9e5da..53b531a 100644 --- a/hw/sensor/src/sensor.c +++ b/hw/sensor/src/sensor.c @@ -60,11 +60,6 @@ struct { SLIST_HEAD(, sensor) mgr_sensor_list; } sensor_mgr; -struct sensor_read_ctx { - sensor_data_func_t user_func; - void *user_arg; -}; - struct sensor_timestamp sensor_base_ts; struct os_callout st_up_osco;