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;
 

Reply via email to