Source-Changes-HG archive

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index][Old Index]

[src/trunk]: src Tests showed that the sensor needs at least 30ms after a MR ...



details:   https://anonhg.NetBSD.org/src/rev/e8bf55893bb2
branches:  trunk
changeset: 810652:e8bf55893bb2
user:      phx <phx%NetBSD.org@localhost>
date:      Wed Sep 09 17:16:20 2015 +0000

description:
Tests showed that the sensor needs at least 30ms after a MR (measurement
request) to have valid data ready, so the driver didn't work very well.
Now the MR is sent in configurable intervals (hw.hythygtemp0.interval)
using callout(9), so that valid data is immediately available for
sysmon's sensor refresh. When the refresh comes too close after the last
MR, then the previous values are used.

diffstat:

 share/man/man4/hythygtemp.4 |   27 ++++-
 sys/dev/i2c/hytp14.c        |  235 ++++++++++++++++++++++++++++++++-----------
 sys/dev/i2c/hytp14var.h     |   27 +---
 3 files changed, 205 insertions(+), 84 deletions(-)

diffs (truncated from 440 to 300 lines):

diff -r 9934b441d5f9 -r e8bf55893bb2 share/man/man4/hythygtemp.4
--- a/share/man/man4/hythygtemp.4       Wed Sep 09 11:56:53 2015 +0000
+++ b/share/man/man4/hythygtemp.4       Wed Sep 09 17:16:20 2015 +0000
@@ -1,4 +1,4 @@
-.\"    $NetBSD: hythygtemp.4,v 1.2 2014/05/18 12:45:03 wiz Exp $
+.\"    $NetBSD: hythygtemp.4,v 1.3 2015/09/09 17:16:20 phx Exp $
 .\"
 .\" Copyright (c) 2014 Frank Kardel
 .\" All rights reserved.
@@ -44,13 +44,28 @@
 .Ar addr
 argument selects the address at the
 .Xr iic 4
-bus.
+bus. The sampling interval can be changed through the
+.Xr sysctl 8
+node
+.Li hw.hythygtemp0.interval .
+.Pp
 The sensor chips can be reconfigured to respond to other addresses than the
-default value of 0x28.
+default value of 0x28 by external utilities, like for example the
+.Pa pkgsrc/sysutils/hytctl
+package.
+.Sh SYSCTL VARIABLES
+The following
+.Xr sysctl 3
+variables are provided:
+.Bl -tag -width indent
+.It hw.hythygtemp0.interval
+Defines the sensor's sampling interval in seconds. It defaults to 50 seconds.
+.El
 .Sh SEE ALSO
 .Xr envsys 4 ,
 .Xr iic 4 ,
-.Xr envstat 8
+.Xr envstat 8 ,
+.Xr sysctl 8
 .Sh HISTORY
 The
 .Nm
@@ -61,4 +76,6 @@
 The
 .Nm
 driver was written by
-.An Frank Kardel Aq Mt kardel%NetBSD.org@localhost .
+.An Frank Kardel Aq Mt kardel%NetBSD.org@localhost
+and
+.An Frank Wille Aq phx%NetBSD.org@localhost .
diff -r 9934b441d5f9 -r e8bf55893bb2 sys/dev/i2c/hytp14.c
--- a/sys/dev/i2c/hytp14.c      Wed Sep 09 11:56:53 2015 +0000
+++ b/sys/dev/i2c/hytp14.c      Wed Sep 09 17:16:20 2015 +0000
@@ -37,16 +37,16 @@
  */ 
 
 #include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: hytp14.c,v 1.4 2015/04/23 23:23:00 pgoyette Exp $");
+__KERNEL_RCSID(0, "$NetBSD: hytp14.c,v 1.5 2015/09/09 17:16:20 phx Exp $");
 
 #include <sys/param.h>
 #include <sys/systm.h>
 #include <sys/kernel.h>
 #include <sys/device.h>
 #include <sys/module.h>
+#include <sys/sysctl.h>
 
 #include <dev/sysmon/sysmonvar.h>
-
 #include <dev/i2c/i2cvar.h>
 #include <dev/i2c/hytp14reg.h>
 #include <dev/i2c/hytp14var.h>
@@ -54,12 +54,14 @@
 static int hytp14_match(device_t, cfdata_t, void *);
 static void hytp14_attach(device_t, device_t, void *);
 static int hytp14_detach(device_t, int);
+static void hytp14_measurement_request(void *);
 static int hytp14_refresh_sensor(struct hytp14_sc *sc);
 static void hytp14_refresh(struct sysmon_envsys *, envsys_data_t *);
 static void hytp14_refresh_humidity(struct hytp14_sc *, envsys_data_t *);
 static void hytp14_refresh_temp(struct hytp14_sc *, envsys_data_t *);
+static int sysctl_hytp14_interval(SYSCTLFN_ARGS);
 
-/* #define HYT_DEBUG 3 */
+/*#define HYT_DEBUG 3*/
 #ifdef HYT_DEBUG
 volatile int hythygtemp_debug = HYT_DEBUG;
 
@@ -91,7 +93,9 @@
 static int
 hytp14_match(device_t parent, cfdata_t match, void *aux)
 {
-       struct i2c_attach_args *ia = aux;
+       struct i2c_attach_args *ia;
+
+       ia = aux;
 
        if (ia->ia_name) {
                /* direct config - check name */
@@ -108,14 +112,17 @@
 static void
 hytp14_attach(device_t parent, device_t self, void *aux)
 {
-       struct hytp14_sc *sc = device_private(self);
-       struct i2c_attach_args *ia = aux;
+       const struct sysctlnode *rnode, *node;
+       struct hytp14_sc *sc;
+       struct i2c_attach_args *ia;
        int i;
 
+       ia = aux;
+       sc = device_private(self);
+
        sc->sc_dev = self;
        sc->sc_tag = ia->ia_tag;
        sc->sc_addr = ia->ia_addr;
-       sc->sc_refresh = 0;
        sc->sc_valid = ENVSYS_SINVALID;
        sc->sc_numsensors = __arraycount(hytp14_sensors);
 
@@ -134,7 +141,7 @@
                sc->sc_sensors[i].state = ENVSYS_SINVALID;
                
                DPRINTF(2, ("hytp14_attach: registering sensor %d (%s)\n", i,
-                           sc->sc_sensors[i].desc));
+                   sc->sc_sensors[i].desc));
                
                if (sysmon_envsys_sensor_attach(sc->sc_sme, &sc->sc_sensors[i])) {
                        aprint_error_dev(sc->sc_dev,
@@ -157,80 +164,158 @@
                return;
        }
 
+       /* create a sysctl node for setting the measurement interval */
+       rnode = node = NULL;
+       sysctl_createv(NULL, 0, NULL, &rnode,
+           CTLFLAG_READWRITE,
+           CTLTYPE_NODE, device_xname(sc->sc_dev), NULL,
+           NULL, 0, NULL, 0,
+           CTL_HW, CTL_CREATE, CTL_EOL);
+
+       if (rnode != NULL)
+               sysctl_createv(NULL, 0, NULL, &node,
+                   CTLFLAG_READWRITE | CTLFLAG_OWNDESC,
+                   CTLTYPE_INT, "interval",
+                   SYSCTL_DESCR("Sensor sampling interval in seconds"),
+                   sysctl_hytp14_interval, 0, (void *)sc, 0,
+                   CTL_HW, rnode->sysctl_num, CTL_CREATE, CTL_EOL);
+
        aprint_normal(": HYT-221/271/939 humidity and temperature sensor\n");
+
+       /* set up callout for the default measurement interval */
+       sc->sc_mrinterval = HYTP14_MR_INTERVAL;
+       callout_init(&sc->sc_mrcallout, 0);
+       callout_setfunc(&sc->sc_mrcallout, hytp14_measurement_request, sc);
+
+       /* issue initial measurement request */
+       hytp14_measurement_request(sc);
 }
 
-static int hytp14_detach(device_t self, int flags)
+static int
+hytp14_detach(device_t self, int flags)
 {
-       struct hytp14_sc *sc = device_private(self);
+       struct hytp14_sc *sc;
+
+       sc = device_private(self);
 
        if (sc->sc_sme != NULL) {
                sysmon_envsys_unregister(sc->sc_sme);
                sc->sc_sme = NULL;
        }
-       
+
+       /* stop our measurement requests */
+       callout_stop(&sc->sc_mrcallout);
+       callout_destroy(&sc->sc_mrcallout);
+
        return 0;
 }
 
+static void
+hytp14_measurement_request(void *aux)
+{
+       uint8_t buf[I2C_EXEC_MAX_BUFLEN];
+       struct hytp14_sc *sc;
+       int error;
+
+       sc = aux;
+       DPRINTF(2, ("%s(%s)\n", __func__, device_xname(sc->sc_dev)));
+
+       error = iic_acquire_bus(sc->sc_tag, 0);
+       if (error == 0) {
+
+               /* send DF command - read last data from sensor */
+               error = iic_exec(sc->sc_tag, I2C_OP_READ_WITH_STOP,
+                   sc->sc_addr, NULL, 0, sc->sc_data, sizeof(sc->sc_data), 0);
+               if (error != 0) {
+                       DPRINTF(2, ("%s: %s: failed read from 0x%02x - error %d\n",
+                           device_xname(sc->sc_dev), __func__,
+                           sc->sc_addr, error));
+               } else {
+                       DPRINTF(3, ("%s(%s): DF success : "
+                           "0x%02x%02x%02x%02x\n",
+                           __func__, device_xname(sc->sc_dev),
+                           sc->sc_data[0], sc->sc_data[1],
+                           sc->sc_data[2], sc->sc_data[3]));
+
+                       /* remember last data, when valid */
+                       if (!(sc->sc_data[0] &
+                           (HYTP14_RESP_CMDMODE | HYTP14_RESP_STALE))) {
+                               memcpy(sc->sc_last, sc->sc_data,
+                                   sizeof(sc->sc_last));
+                               sc->sc_valid = ENVSYS_SVALID;
+                       }
+               }
+
+               /* send MR command to request a new measurement */
+               error = iic_exec(sc->sc_tag, I2C_OP_WRITE_WITH_STOP,
+                   sc->sc_addr, NULL, 0, buf, sizeof(buf), 0);
+
+                if (error == 0) {
+                       DPRINTF(3, ("%s(%s): MR sent\n",
+                           __func__, device_xname(sc->sc_dev)));
+               } else {
+                       DPRINTF(2, ("%s: %s: failed read from 0x%02x - error %d\n",
+                           device_xname(sc->sc_dev), __func__,
+                           sc->sc_addr, error));
+               }
+
+               iic_release_bus(sc->sc_tag, 0); 
+               DPRINTF(3, ("%s(%s): bus released\n",
+                   __func__, device_xname(sc->sc_dev)));
+       } else {
+               DPRINTF(2, ("%s: %s: failed acquire i2c bus - error %d\n",
+                   device_xname(sc->sc_dev), __func__, error));
+       }
+
+       /* schedule next measurement interval */
+       callout_schedule(&sc->sc_mrcallout, sc->sc_mrinterval * hz);
+}
+
 static int
 hytp14_refresh_sensor(struct hytp14_sc *sc)
 {
-       int error = 0;
-       uint8_t buf[I2C_EXEC_MAX_BUFLEN];
-
-       /* no more than once per second */
-       if (hardclock_ticks - sc->sc_refresh < hz)
-               return sc->sc_valid;
-       
-       DPRINTF(2, ("hytp14_refresh_sensor(%s)\n", device_xname(sc->sc_dev)));
+       int error;
 
-       if ((error = iic_acquire_bus(sc->sc_tag, 0)) == 0) {
-               DPRINTF(3, ("hytp14_refresh_sensor(%s): bus locked\n", device_xname(sc->sc_dev)));
+       DPRINTF(2, ("%s(%s)\n", __func__, device_xname(sc->sc_dev)));
 
-               /* send MR command */
-                /* avoid quick read/write by providing a result buffer */
-               error = iic_exec(sc->sc_tag, I2C_OP_WRITE_WITH_STOP,
-                                sc->sc_addr, NULL, 0, buf, sizeof buf, 0);
-                if (error == 0) {
-                       DPRINTF(3, ("hytp14_refresh_sensor(%s): MR sent\n",
-                                   device_xname(sc->sc_dev)));
+       error = iic_acquire_bus(sc->sc_tag, 0);
+       if (error == 0) {
 
-                       /* send DF command - read data from sensor */
-                       error = iic_exec(sc->sc_tag, I2C_OP_READ_WITH_STOP,
-                                        sc->sc_addr, NULL, 0, sc->sc_data,
-                                             sizeof sc->sc_data, 0);
-                        if (error != 0) {
-                               DPRINTF(2, ("%s: %s: failed read from 0x%02x - error %d\n",
-                                           device_xname(sc->sc_dev),
-                                           __func__, sc->sc_addr, error));
-                       } else {
-                               DPRINTF(2, ("hytp14_refresh_sensor(%s): DF success : 0x%02x%02x%02x%02x\n",
-                                           device_xname(sc->sc_dev),
-                                           sc->sc_data[0],
-                                           sc->sc_data[1],
-                                           sc->sc_data[2],
-                                           sc->sc_data[3]));
-                       }
+               /* send DF command - read last data from sensor */
+               error = iic_exec(sc->sc_tag, I2C_OP_READ_WITH_STOP,
+                   sc->sc_addr, NULL, 0, sc->sc_data, sizeof(sc->sc_data), 0);
+               if (error != 0) {
+                       DPRINTF(2, ("%s: %s: failed read from 0x%02x - error %d\n",
+                           device_xname(sc->sc_dev), __func__,
+                           sc->sc_addr, error));
                } else {
-                       DPRINTF(2, ("%s: %s: failed read from 0x%02x - error %d\n",
-                                   device_xname(sc->sc_dev), __func__,
-                                   sc->sc_addr, error));
+                       DPRINTF(3, ("%s(%s): DF success : "
+                           "0x%02x%02x%02x%02x\n",
+                           __func__, device_xname(sc->sc_dev),
+                           sc->sc_data[0], sc->sc_data[1],



Home | Main Index | Thread Index | Old Index