Module Name: src
Committed By: christos
Date: Fri Nov 12 22:16:28 UTC 2021
Modified Files:
src/sys/dev/i2c: sht3x.c
Log Message:
simplify the code and remove unused (it is in CVS anyway). Try to merge
duplicate code. Follow KNF. Brad, please test!
To generate a diff of this commit:
cvs rdiff -u -r1.1 -r1.2 src/sys/dev/i2c/sht3x.c
Please note that diffs are not public domain; they are subject to the
copyright notices on the relevant files.
Modified files:
Index: src/sys/dev/i2c/sht3x.c
diff -u src/sys/dev/i2c/sht3x.c:1.1 src/sys/dev/i2c/sht3x.c:1.2
--- src/sys/dev/i2c/sht3x.c:1.1 Sat Nov 6 09:34:40 2021
+++ src/sys/dev/i2c/sht3x.c Fri Nov 12 17:16:27 2021
@@ -1,4 +1,4 @@
-/* $NetBSD: sht3x.c,v 1.1 2021/11/06 13:34:40 brad Exp $ */
+/* $NetBSD: sht3x.c,v 1.2 2021/11/12 22:16:27 christos Exp $ */
/*
* Copyright (c) 2021 Brad Spencer <[email protected]>
@@ -17,7 +17,7 @@
*/
#include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: sht3x.c,v 1.1 2021/11/06 13:34:40 brad Exp $");
+__KERNEL_RCSID(0, "$NetBSD: sht3x.c,v 1.2 2021/11/12 22:16:27 christos Exp $");
/*
Driver for the Sensirion SHT30/SHT31/SHT35
@@ -52,17 +52,6 @@ static int sht3x_match(device_t, cfdata
static void sht3x_attach(device_t, device_t, void *);
static int sht3x_detach(device_t, int);
static void sht3x_refresh(struct sysmon_envsys *, envsys_data_t *);
-/* The chip that I had would not allow the limits to actually be set
- * for reasons which are not obvious. The chip took the command just
- * fine, but a read back of the limit registers showed that no change
- * was made, so disable limits for now.
- */
-#ifdef __did_not_work
-static void sht3x_get_limits(struct sysmon_envsys *, envsys_data_t *,
- sysmon_envsys_lim_t *, uint32_t *);
-static void sht3x_set_limits(struct sysmon_envsys *, envsys_data_t *,
- sysmon_envsys_lim_t *, uint32_t *);
-#endif
static int sht3x_verify_sysctl(SYSCTLFN_ARGS);
static int sht3x_verify_sysctl_heateron(SYSCTLFN_ARGS);
static int sht3x_verify_sysctl_modes(SYSCTLFN_ARGS);
@@ -338,8 +327,8 @@ sht3x_take_break(void *aux, bool have_bu
if (! have_bus) {
error = iic_acquire_bus(sc->sc_tag, 0);
if (error) {
- DPRINTF(sc, 2, ("%s: Could not acquire iic bus for breaking %d\n",
- device_xname(sc->sc_dev), error));
+ DPRINTF(sc, 2, ("%s: Could not acquire iic bus for "
+ "breaking %d\n", device_xname(sc->sc_dev), error));
goto out;
}
}
@@ -348,13 +337,13 @@ sht3x_take_break(void *aux, bool have_bu
DPRINTF(sc, 2, ("%s: Error breaking: %d\n",
device_xname(sc->sc_dev), error));
}
- out:
+out:
if (! have_bus) {
iic_release_bus(sc->sc_tag, 0);
}
sc->sc_isperiodic = false;
- strlcpy(sc->sc_mode,"single-shot",SHT3X_MODE_NAME);
+ strlcpy(sc->sc_mode, "single-shot", SHT3X_MODE_NAME);
return error;
}
@@ -362,56 +351,53 @@ sht3x_take_break(void *aux, bool have_bu
static int
sht3x_get_status_register(void *aux, uint16_t *reg, bool have_bus)
{
- struct sht3x_sc *sc;
- sc = aux;
+ struct sht3x_sc *sc = aux;
uint8_t buf[3];
- int error = 0;
+ int error;
if (! have_bus) {
error = iic_acquire_bus(sc->sc_tag, 0);
if (error) {
- DPRINTF(sc, 2, ("%s: Could not acquire iic bus for getting status %d\n",
- device_xname(sc->sc_dev), error));
- goto out;
+ DPRINTF(sc, 2, ("%s: Could not acquire iic bus for "
+ "getting status %d\n", device_xname(sc->sc_dev),
+ error));
+ return error;
}
}
error = sht3x_cmdr(sc, SHT3X_GET_STATUS_REGISTER, buf, 3);
if (error) {
DPRINTF(sc, 2, ("%s: Error getting status: %d\n",
device_xname(sc->sc_dev), error));
+ goto out;
}
- out:
+
+ uint8_t c = sht3x_crc(&buf[0], 2);
+ if (c == buf[2]) {
+ *reg = buf[0] << 8 | buf[1];
+ } else {
+ error = EINVAL;
+ }
+out:
if (! have_bus) {
iic_release_bus(sc->sc_tag, 0);
}
- if (!error) {
- uint8_t c;
-
- c = sht3x_crc(&buf[0],2);
- if (c == buf[2]) {
- *reg = buf[0] << 8 | buf[1];
- } else {
- error = EINVAL;
- }
- }
-
return error;
}
static int
sht3x_clear_status_register(void *aux, bool have_bus)
{
- struct sht3x_sc *sc;
- sc = aux;
- int error = 0;
+ struct sht3x_sc *sc = aux;
+ int error;
if (! have_bus) {
error = iic_acquire_bus(sc->sc_tag, 0);
if (error) {
- DPRINTF(sc, 2, ("%s: Could not acquire iic bus for clearing status %d\n",
- device_xname(sc->sc_dev), error));
- goto out;
+ DPRINTF(sc, 2, ("%s: Could not acquire iic bus for "
+ "clearing status %d\n", device_xname(sc->sc_dev),
+ error));
+ return error;
}
}
error = sht3x_cmdr(sc, SHT3X_CLEAR_STATUS_REGISTER, NULL, 0);
@@ -419,7 +405,6 @@ sht3x_clear_status_register(void *aux, b
DPRINTF(sc, 2, ("%s: Error clear status register: %d\n",
device_xname(sc->sc_dev), error));
}
- out:
if (! have_bus) {
iic_release_bus(sc->sc_tag, 0);
}
@@ -438,16 +423,18 @@ sht3x_thread(void *aux)
while (!sc->sc_stopping && !sc->sc_dying) {
if (sc->sc_initperiodic) {
- error = sht3x_init_periodic_measurement(sc,&sdelay);
+ error = sht3x_init_periodic_measurement(sc, &sdelay);
if (error) {
- DPRINTF(sc, 2, ("%s: Error initing periodic measurement "
- "in thread: %d\n", device_xname(sc->sc_dev), error));
+ DPRINTF(sc, 2, ("%s: Error initing periodic "
+ "measurement in thread: %d\n",
+ device_xname(sc->sc_dev), error));
}
sc->sc_initperiodic = false;
}
rv = cv_timedwait(&sc->sc_condvar, &sc->sc_threadmutex,
mstohz(sdelay));
- if (rv == EWOULDBLOCK && !sc->sc_stopping && !sc->sc_initperiodic && !sc->sc_dying) {
+ if (rv == EWOULDBLOCK && !sc->sc_stopping &&
+ !sc->sc_initperiodic && !sc->sc_dying) {
sht3x_take_periodic_measurement(sc);
}
}
@@ -458,14 +445,17 @@ sht3x_thread(void *aux)
int
sht3x_init_periodic_measurement(void *aux, int *sdelay)
{
- struct sht3x_sc *sc;
- sc = aux;
- int i,error = 0;
- uint16_t r = 0;
+ struct sht3x_sc *sc = aux;
+ size_t i;
+ int error;
+ uint16_t r;
for (i = 0; i < __arraycount(sht3x_periodic_rate); i++) {
- if (strncmp(sc->sc_repeatability,sht3x_periodic_rate[i].repeatability,SHT3X_REP_NAME) == 0 &&
- strncmp(sc->sc_periodic_rate, sht3x_periodic_rate[i].rate,SHT3X_RATE_NAME) == 0) {
+ if (strncmp(sc->sc_repeatability,
+ sht3x_periodic_rate[i].repeatability, SHT3X_REP_NAME) == 0 &&
+ strncmp(sc->sc_periodic_rate, sht3x_periodic_rate[i].rate,
+ SHT3X_RATE_NAME) == 0)
+ {
r = sht3x_periodic_rate[i].cmd;
*sdelay = sht3x_periodic_rate[i].sdelay;
break;
@@ -473,123 +463,138 @@ sht3x_init_periodic_measurement(void *au
}
if (i == __arraycount(sht3x_periodic_rate)) {
- error = 1;
*sdelay = 100;
+ return ENODEV;
}
DPRINTF(sc, 2, ("%s: Would init with: %x\n",
device_xname(sc->sc_dev), r));
- if (error == 0) {
- mutex_enter(&sc->sc_mutex);
+ mutex_enter(&sc->sc_mutex);
- error = iic_acquire_bus(sc->sc_tag, 0);
- if (error) {
- DPRINTF(sc, 2, ("%s: Could not acquire iic bus for initing: "
- " %d\n", device_xname(sc->sc_dev), error));
- } else {
- error = sht3x_take_break(sc,true);
- if (error) {
- DPRINTF(sc, 2, ("%s: Could not acquire iic bus for initing: "
- " %d\n", device_xname(sc->sc_dev), error));
- }
+ error = iic_acquire_bus(sc->sc_tag, 0);
+ if (error) {
+ DPRINTF(sc, 2, ("%s: Could not acquire iic bus for initing: "
+ " %d\n", device_xname(sc->sc_dev), error));
+ goto out;
+ }
- error = sht3x_cmdr(sc, r, NULL, 0);
- if (error) {
- DPRINTF(sc, 2, ("%s: Error sending periodic measurement command: %d\n",
- device_xname(sc->sc_dev), error));
- }
- iic_release_bus(sc->sc_tag, 0);
- sc->sc_isperiodic = true;
- strlcpy(sc->sc_mode,"periodic",SHT3X_MODE_NAME);
- }
- mutex_exit(&sc->sc_mutex);
+ error = sht3x_take_break(sc, true);
+ if (error) {
+ DPRINTF(sc, 2, ("%s: Could not acquire iic bus for initing: "
+ " %d\n", device_xname(sc->sc_dev), error));
+ goto out;
+ }
+
+ error = sht3x_cmdr(sc, r, NULL, 0);
+ if (error) {
+ DPRINTF(sc, 2,
+ ("%s: Error sending periodic measurement command: %d\n",
+ device_xname(sc->sc_dev), error));
+ goto out;
}
+ sc->sc_isperiodic = true;
+ strlcpy(sc->sc_mode, "periodic", SHT3X_MODE_NAME);
+
+out:
+ iic_release_bus(sc->sc_tag, 0);
+ mutex_exit(&sc->sc_mutex);
return error;
}
static void
sht3x_take_periodic_measurement(void *aux)
{
- struct sht3x_sc *sc;
- sc = aux;
- int error = 0, data_error = 0;
- uint8_t rawbuf[6];
+ struct sht3x_sc *sc = aux;
+ int error;
struct sht3x_read_q *pp;
+ uint8_t rawbuf[MAX(sizeof(sc->sc_pbuffer), sizeof(pp->measurement))];
+ uint16_t status_reg;
mutex_enter(&sc->sc_mutex);
error = iic_acquire_bus(sc->sc_tag, 0);
if (error) {
DPRINTF(sc, 2, ("%s: Could not acquire iic bus for getting "
"periodic data: %d\n", device_xname(sc->sc_dev), error));
- } else {
- uint16_t status_reg;
+ goto out;
+ }
- error = sht3x_get_status_register(sc, &status_reg, true);
- if (error) {
- DPRINTF(sc, 2, ("%s: Error getting status register periodic: %d\n",
- device_xname(sc->sc_dev), error));
- } else {
- if (status_reg & SHT3X_RESET_DETECTED) {
- aprint_error_dev(sc->sc_dev, "Reset detected in periodic mode. Heater may have been reset.\n");
- delay(3000);
- sht3x_take_break(sc,true);
- sht3x_clear_status_register(sc, true);
- sc->sc_heateron = status_reg & SHT3X_HEATER_STATUS;
- sc->sc_initperiodic = true;
- } else {
- data_error = sht3x_cmdr(sc, SHT3X_PERIODIC_FETCH_DATA, rawbuf, 6);
- /* EIO is actually expected if the poll interval is faster
- * than the rate that the sensor is set to. Unfortunally,
- * this will also mess with the ability to detect an actual problem
- * with the sensor in periodic mode, so we do the best we can here.
- */
- if (data_error && data_error != EIO) {
- DPRINTF(sc, 2, ("%s: Error sending periodic fetch command: %d\n",
- device_xname(sc->sc_dev), data_error));
- }
- }
- }
- iic_release_bus(sc->sc_tag, 0);
- /* If there was no errors from anything then the data should be
- * valid.
+ error = sht3x_get_status_register(sc, &status_reg, true);
+ if (error) {
+ DPRINTF(sc, 2,
+ ("%s: Error getting status register periodic: %d\n",
+ device_xname(sc->sc_dev), error));
+ goto err;
+ }
+
+ if (status_reg & SHT3X_RESET_DETECTED) {
+ aprint_error_dev(sc->sc_dev, "Reset detected in periodic mode. "
+ "Heater may have been reset.\n");
+ delay(3000);
+ sht3x_take_break(sc, true);
+ sht3x_clear_status_register(sc, true);
+ sc->sc_heateron = status_reg & SHT3X_HEATER_STATUS;
+ sc->sc_initperiodic = true;
+ } else {
+ int data_error = sht3x_cmdr(sc, SHT3X_PERIODIC_FETCH_DATA,
+ rawbuf, sizeof(rawbuf));
+ /*
+ * EIO is actually expected if the poll interval is faster
+ * than the rate that the sensor is set to. Unfortunally,
+ * this will also mess with the ability to detect an actual
+ * problem with the sensor in periodic mode, so we do the best
+ * we can here.
*/
- if (!data_error && !error) {
- DPRINTF(sc, 2, ("%s: Raw periodic: %x%x - %x -- %x%x - %x\n",
- device_xname(sc->sc_dev), rawbuf[0], rawbuf[1], rawbuf[2],
- rawbuf[3], rawbuf[4], rawbuf[5]));
- memcpy(sc->sc_pbuffer,rawbuf,6);
-
- if (sc->sc_opened) {
- mutex_enter(&sc->sc_read_mutex);
- pp = pool_cache_get(sc->sc_readpool,PR_NOWAIT);
- if (pp != NULL) {
- memcpy(pp->measurement,rawbuf,6);
- DPRINTF(sc, 4, ("%s: Queue insert\n",device_xname(sc->sc_dev)));
- SIMPLEQ_INSERT_HEAD(&sc->sc_read_queue,pp,read_q);
- } else {
- aprint_error("Could not allocate memory for pool read\n");
- }
- cv_signal(&sc->sc_condreadready);
- mutex_exit(&sc->sc_read_mutex);
+ if (data_error) {
+ if (data_error != EIO) {
+ DPRINTF(sc, 2, ("%s: Error sending periodic "
+ "fetch command: %d\n",
+ device_xname(sc->sc_dev), data_error));
}
+ goto err;
+ }
+ }
+ iic_release_bus(sc->sc_tag, 0);
+ /*
+ * If there was no errors from anything then the data should be
+ * valid.
+ */
+ DPRINTF(sc, 2, ("%s: Raw periodic: %x%x - %x -- %x%x - %x\n",
+ device_xname(sc->sc_dev), rawbuf[0], rawbuf[1], rawbuf[2],
+ rawbuf[3], rawbuf[4], rawbuf[5]));
+ memcpy(sc->sc_pbuffer, rawbuf, sizeof(sc->sc_pbuffer));
+
+ if (sc->sc_opened) {
+ mutex_enter(&sc->sc_read_mutex);
+ pp = pool_cache_get(sc->sc_readpool, PR_NOWAIT);
+ if (pp == NULL) {
+ aprint_error_dev(sc->sc_dev,
+ "Could not allocate memory for pool read\n");
} else {
- /* We are only going to worry about errors when it was not related
- * to actually getting data. That is a likely indicator of a problem
- * with the sensor.
- */
- if (error) {
- DPRINTF(sc, 2, ("%s: Raw periodic with error: %x%x - %x -- %x%x - %x -- %d\n",
- device_xname(sc->sc_dev), rawbuf[0], rawbuf[1], rawbuf[2],
- rawbuf[3], rawbuf[4], rawbuf[5], error));
- uint8_t bad[6] = "dedbef";
- memcpy(sc->sc_pbuffer, bad, 6);
- }
+ memcpy(pp->measurement, rawbuf, sizeof(pp->measurement));
+ DPRINTF(sc, 4, ("%s: Queue insert\n",
+ device_xname(sc->sc_dev)));
+ SIMPLEQ_INSERT_HEAD(&sc->sc_read_queue, pp, read_q);
}
-
+ cv_signal(&sc->sc_condreadready);
+ mutex_exit(&sc->sc_read_mutex);
}
+out:
+ mutex_exit(&sc->sc_mutex);
+ return;
+err:
+ /*
+ * We are only going to worry about errors when it was not related
+ * to actually getting data. That is a likely indicator of a problem
+ * with the sensor.
+ */
+ DPRINTF(sc, 2, ("%s: Raw periodic with error: %x%x - %x -- "
+ "%x%x - %x -- %d\n", device_xname(sc->sc_dev), rawbuf[0], rawbuf[1],
+ rawbuf[2], rawbuf[3], rawbuf[4], rawbuf[5], error));
+ iic_release_bus(sc->sc_tag, 0);
+ memcpy(sc->sc_pbuffer, "dedbef", sizeof(sc->sc_pbuffer));
mutex_exit(&sc->sc_mutex);
}
@@ -685,7 +690,7 @@ sht3x_set_heater(struct sht3x_sc *sc)
if (error) {
DPRINTF(sc, 2, ("%s:%s: Failed to acquire bus: %d\n",
device_xname(sc->sc_dev), __func__, error));
- return error;
+ goto out;
}
if (sc->sc_heateron) {
@@ -697,6 +702,7 @@ sht3x_set_heater(struct sht3x_sc *sc)
error = sht3x_cmdr(sc, cmd, NULL, 0);
iic_release_bus(sc->sc_tag,0);
+out:
mutex_exit(&sc->sc_mutex);
return error;
@@ -708,9 +714,9 @@ sht3x_verify_sysctl_modes(SYSCTLFN_ARGS)
char buf[SHT3X_MODE_NAME];
struct sht3x_sc *sc;
struct sysctlnode node;
- int error = 0;
bool is_ss = false;
bool is_periodic = false;
+ int error;
node = *rnode;
sc = node.sysctl_data;
@@ -724,31 +730,30 @@ sht3x_verify_sysctl_modes(SYSCTLFN_ARGS)
return EINVAL;
}
- is_ss = (strncmp(node.sysctl_data, "single-shot", SHT3X_MODE_NAME) == 0);
- is_periodic = (strncmp(node.sysctl_data, "periodic", SHT3X_MODE_NAME) == 0);
+ is_ss = strncmp(node.sysctl_data, "single-shot", SHT3X_MODE_NAME) == 0;
+ is_periodic = strncmp(node.sysctl_data, "periodic", SHT3X_MODE_NAME)
+ == 0;
- if (is_ss || is_periodic) {
- (void) memcpy(sc->sc_mode, node.sysctl_data, SHT3X_MODE_NAME);
- } else {
- error = EINVAL;
+ if (!is_ss && !is_periodic) {
+ return EINVAL;
}
- if (error == 0) {
- if (is_ss) {
- sht3x_stop_thread(sc);
- sc->sc_stopping = false;
- sc->sc_initperiodic = false;
- sc->sc_isperiodic = false;
- }
- if (is_periodic) {
- sc->sc_stopping = false;
- sc->sc_initperiodic = true;
- sc->sc_isperiodic = true;
- sht3x_start_thread(sc);
- }
+ (void) memcpy(sc->sc_mode, node.sysctl_data, SHT3X_MODE_NAME);
+ if (is_ss) {
+ sht3x_stop_thread(sc);
+ sc->sc_stopping = false;
+ sc->sc_initperiodic = false;
+ sc->sc_isperiodic = false;
}
- return error;
+ if (is_periodic) {
+ sc->sc_stopping = false;
+ sc->sc_initperiodic = true;
+ sc->sc_isperiodic = true;
+ sht3x_start_thread(sc);
+ }
+
+ return 0;
}
int
@@ -757,7 +762,7 @@ sht3x_verify_sysctl_repeatability(SYSCTL
char buf[SHT3X_REP_NAME];
struct sht3x_sc *sc;
struct sysctlnode node;
- int error = 0;
+ int error;
size_t i;
node = *rnode;
@@ -792,7 +797,7 @@ sht3x_verify_sysctl_rate(SYSCTLFN_ARGS)
char buf[SHT3X_RATE_NAME];
struct sht3x_sc *sc;
struct sysctlnode node;
- int error = 0;
+ int error;
size_t i;
node = *rnode;
@@ -812,6 +817,7 @@ sht3x_verify_sysctl_rate(SYSCTLFN_ARGS)
if (i == __arraycount(sht3x_periodic_rate))
return EINVAL;
+
(void) memcpy(sc->sc_periodic_rate, node.sysctl_data, SHT3X_RATE_NAME);
if (sc->sc_isperiodic) {
@@ -824,20 +830,18 @@ sht3x_verify_sysctl_rate(SYSCTLFN_ARGS)
static int
sht3x_cmddelay(uint16_t cmd)
{
- int r = -2;
+ size_t i;
- for(int i = 0;i < __arraycount(sht3x_timings);i++) {
+ for (i = 0; i < __arraycount(sht3x_timings); i++) {
if (cmd == sht3x_timings[i].cmd) {
- r = sht3x_timings[i].typicaldelay;
break;
}
}
- if (r == -2) {
- r = -1;
+ if (i == __arraycount(sht3x_timings)) {
+ return -1;
}
-
- return r;
+ return sht3x_timings[i].typicaldelay;
}
static int
@@ -854,23 +858,27 @@ sht3x_cmd(i2c_tag_t tag, i2c_addr_t addr
cmd8[0] = cmd[0] >> 8;
cmd8[1] = cmd[0] & 0x00ff;
- error = iic_exec(tag,I2C_OP_WRITE_WITH_STOP,addr,&cmd8[0],clen,NULL,0,0);
+ error = iic_exec(tag, I2C_OP_WRITE_WITH_STOP, addr, &cmd8[0], clen,
+ NULL, 0, 0);
+ if (error)
+ return error;
- if (error == 0) {
- cmddelay = sht3x_cmddelay(cmd[0]);
- if (cmddelay != -1) {
- delay(cmddelay);
- }
+ cmddelay = sht3x_cmddelay(cmd[0]);
+ if (cmddelay != -1) {
+ delay(cmddelay);
+ }
- /* Not all commands return anything */
- if (blen > 0) {
- for (int aint = 0; aint < readattempts; aint++) {
- error = iic_exec(tag,I2C_OP_READ_WITH_STOP,addr,NULL,0,buf,blen,0);
- if (error == 0)
- break;
- delay(1000);
- }
- }
+ /* Not all commands return anything */
+ if (blen == 0) {
+ return 0;
+ }
+
+ for (int aint = 0; aint < readattempts; aint++) {
+ error = iic_exec(tag, I2C_OP_READ_WITH_STOP, addr, NULL, 0, buf,
+ blen, 0);
+ if (error == 0)
+ break;
+ delay(1000);
}
return error;
@@ -879,11 +887,12 @@ sht3x_cmd(i2c_tag_t tag, i2c_addr_t addr
static int
sht3x_cmdr(struct sht3x_sc *sc, uint16_t cmd, uint8_t *buf, size_t blen)
{
- return sht3x_cmd(sc->sc_tag, sc->sc_addr, &cmd, 2, buf, blen, sc->sc_readattempts);
+ return sht3x_cmd(sc->sc_tag, sc->sc_addr, &cmd, 2, buf, blen,
+ sc->sc_readattempts);
}
static uint8_t
-sht3x_crc(uint8_t * data, size_t size)
+sht3x_crc(uint8_t *data, size_t size)
{
uint8_t crc = 0xFF;
@@ -1020,25 +1029,24 @@ sht3x_match(device_t parent, cfdata_t ma
}
/* indirect config - check for configured address */
- if (ia->ia_addr == SHT3X_TYPICAL_ADDR_1 ||
- ia->ia_addr == SHT3X_TYPICAL_ADDR_2) {
- /*
- * Check to see if something is really at this i2c address. This will
- * keep phantom devices from appearing
- */
- if (iic_acquire_bus(ia->ia_tag, 0) != 0) {
- if (matchdebug)
- printf("in match acquire bus failed\n");
- return 0;
- }
-
- error = sht3x_poke(ia->ia_tag, ia->ia_addr, matchdebug);
- iic_release_bus(ia->ia_tag, 0);
+ if (ia->ia_addr != SHT3X_TYPICAL_ADDR_1 &&
+ ia->ia_addr != SHT3X_TYPICAL_ADDR_2)
+ return 0;
- return error == 0 ? I2C_MATCH_ADDRESS_AND_PROBE : 0;
- } else {
+ /*
+ * Check to see if something is really at this i2c address.
+ * This will keep phantom devices from appearing
+ */
+ if (iic_acquire_bus(ia->ia_tag, 0) != 0) {
+ if (matchdebug)
+ printf("in match acquire bus failed\n");
return 0;
}
+
+ error = sht3x_poke(ia->ia_tag, ia->ia_addr, matchdebug);
+ iic_release_bus(ia->ia_tag, 0);
+
+ return error == 0 ? I2C_MATCH_ADDRESS_AND_PROBE : 0;
}
static void
@@ -1059,10 +1067,10 @@ sht3x_attach(device_t parent, device_t s
sc->sc_tag = ia->ia_tag;
sc->sc_addr = ia->ia_addr;
sc->sc_sht3xdebug = 0;
- strlcpy(sc->sc_mode,"single-shot",SHT3X_MODE_NAME);
+ strlcpy(sc->sc_mode, "single-shot", SHT3X_MODE_NAME);
sc->sc_isperiodic = false;
- strlcpy(sc->sc_repeatability,"high",SHT3X_REP_NAME);
- strlcpy(sc->sc_periodic_rate,"1.0mps",SHT3X_RATE_NAME);
+ strlcpy(sc->sc_repeatability, "high", SHT3X_REP_NAME);
+ strlcpy(sc->sc_periodic_rate, "1.0mps", SHT3X_RATE_NAME);
sc->sc_readattempts = 10;
sc->sc_ignorecrc = false;
sc->sc_heateron = false;
@@ -1096,7 +1104,8 @@ sht3x_attach(device_t parent, device_t s
}
sc->sc_readpoolname = kmem_asprintf("sht3xrp%d",device_unit(self));
- sc->sc_readpool = pool_cache_init(sizeof(struct sht3x_read_q),0,0,0,sc->sc_readpoolname,NULL,IPL_VM,NULL,NULL,NULL);
+ sc->sc_readpool = pool_cache_init(sizeof(struct sht3x_read_q), 0, 0, 0,
+ sc->sc_readpoolname, NULL, IPL_VM, NULL, NULL, NULL);
pool_cache_sethiwat(sc->sc_readpool,100);
SIMPLEQ_INIT(&sc->sc_read_queue);
@@ -1141,8 +1150,9 @@ sht3x_attach(device_t parent, device_t s
sncrcpt2 = sht3x_crc(&buf[3],2);
serialnumber = (buf[0] << 24) | (buf[1] << 16) | (buf[3] << 8) | buf[4];
- DPRINTF(sc, 2, ("%s: read serial number values: %02x%02x - %02x - %02x%02x - %02x -- %02x %02x\n",
- device_xname(sc->sc_dev), buf[0], buf[1], buf[2], buf[3], buf[4], buf[5], sncrcpt1, sncrcpt2));
+ DPRINTF(sc, 2, ("%s: read serial number values: %02x%02x - %02x - "
+ "%02x%02x - %02x -- %02x %02x\n", device_xname(sc->sc_dev), buf[0],
+ buf[1], buf[2], buf[3], buf[4], buf[5], sncrcpt1, sncrcpt2));
iic_release_bus(sc->sc_tag, 0);
if (error != 0) {
@@ -1156,9 +1166,6 @@ sht3x_attach(device_t parent, device_t s
sc->sc_sensors[i].units = sht3x_sensors[i].type;
sc->sc_sensors[i].state = ENVSYS_SINVALID;
-#ifdef __did_not_work
- sc->sc_sensors[i].flags |= ENVSYS_FMONLIMITS;
-#endif
DPRINTF(sc, 2, ("%s: registering sensor %d (%s)\n", __func__, i,
sc->sc_sensors[i].desc));
@@ -1175,30 +1182,25 @@ sht3x_attach(device_t parent, device_t s
sc->sc_sme->sme_name = device_xname(sc->sc_dev);
sc->sc_sme->sme_cookie = sc;
sc->sc_sme->sme_refresh = sht3x_refresh;
-#ifdef __did_not_work
- sc->sc_sme->sme_get_limits = sht3x_get_limits;
- sc->sc_sme->sme_set_limits = sht3x_set_limits;
-#endif
DPRINTF(sc, 2, ("sht3x_attach: registering with envsys\n"));
if (sysmon_envsys_register(sc->sc_sme)) {
- aprint_error_dev(self,
- "unable to register with sysmon\n");
+ aprint_error_dev(self, "unable to register with sysmon\n");
sysmon_envsys_destroy(sc->sc_sme);
sc->sc_sme = NULL;
return;
}
- /* There is no documented way to ask the chip what version it is. This
- is likely fine as the only apparent difference is in how precise the
- measurements will be. The actual conversation with the chip is
- identical no matter which one you are talking to.
- */
+ /*
+ * There is no documented way to ask the chip what version it is. This
+ * is likely fine as the only apparent difference is in how precise the
+ * measurements will be. The actual conversation with the chip is
+ * identical no matter which one you are talking to.
+ */
aprint_normal_dev(self, "Sensirion SHT30/SHT31/SHT35, "
- "Serial number: %x%s",
- serialnumber,
+ "Serial number: %x%s", serialnumber,
(sncrcpt1 == buf[2] && sncrcpt2 == buf[5]) ? "\n" : " (bad crc)\n");
return;
out:
@@ -1207,7 +1209,7 @@ out:
}
static uint16_t
-sht3x_compute_measure_command_ss(char *repeatability)
+sht3x_compute_measure_command_ss(const char *repeatability)
{
int i;
uint16_t r;
@@ -1221,33 +1223,34 @@ sht3x_compute_measure_command_ss(char *r
}
if (i == __arraycount(sht3x_repeatability_ss))
- panic("Single-shot could not find command for repeatability: %s\n", repeatability);
+ panic("Single-shot could not find command for "
+ "repeatability: %s\n", repeatability);
return r;
}
/*
- The documented conversion calculations for the raw values are as follows:
-
- %RH = (-6 + 125 * rawvalue / 65535)
-
- T in Celsius = (-45 + 175 * rawvalue / 65535)
-
- It follows then:
-
- T in Kelvin = (228.15 + 175 * rawvalue / 65535)
-
- given the relationship between Celsius and Kelvin
-
- What follows reorders the calculation a bit and scales it up to avoid
- the use of any floating point. All that would really have to happen
- is a scale up to 10^6 for the sysenv framework, which wants
- temperature in micro-kelvin and percent relative humidity scaled up
- 10^6, but since this conversion uses 64 bits due to intermediate
- values that are bigger than 32 bits the conversion first scales up to
- 10^9 and the scales back down by 10^3 at the end. This preserves some
- precision in the conversion that would otherwise be lost.
-*/
+ * The documented conversion calculations for the raw values are as follows:
+ *
+ * %RH = (-6 + 125 * rawvalue / 65535)
+ *
+ * T in Celsius = (-45 + 175 * rawvalue / 65535)
+ *
+ * It follows then:
+ *
+ * T in Kelvin = (228.15 + 175 * rawvalue / 65535)
+ *
+ * given the relationship between Celsius and Kelvin
+ *
+ * What follows reorders the calculation a bit and scales it up to avoid
+ * the use of any floating point. All that would really have to happen
+ * is a scale up to 10^6 for the sysenv framework, which wants
+ * temperature in micro-kelvin and percent relative humidity scaled up
+ * 10^6, but since this conversion uses 64 bits due to intermediate
+ * values that are bigger than 32 bits the conversion first scales up to
+ * 10^9 and the scales back down by 10^3 at the end. This preserves some
+ * precision in the conversion that would otherwise be lost.
+ */
static uint64_t
sht3x_compute_temp_from_raw(uint8_t msb, uint8_t lsb) {
@@ -1301,572 +1304,127 @@ sht3x_compute_rh_from_raw(uint8_t msb, u
return q;
}
-/* These are the the same as above except solved for the raw tick rather than
- * temperature or humidity. These are needed for setting the alert limits, but
- * since that did not work, disable these too for now.
- */
-#ifdef __did_not_work
-static uint16_t
-sht3x_compute_raw_from_temp(uint32_t temp)
-{
- uint64_t i1;
- uint32_t tempc;
-
- tempc = temp - 272150000;
- tempc = tempc / 1000000;
-
- i1 = (13107 * tempc) + 589815;
- return (uint16_t)(i1 / 35);
-}
-
-static uint16_t
-sht3x_compute_raw_from_rh(uint32_t mrh)
-{
- uint64_t i1;
- uint32_t rh;
-
- rh = mrh / 1000000;
-
- i1 = 13107 * rh;
- return (uint16_t)(i1 / 20);
-}
-#endif
-
-static void
-sht3x_refresh(struct sysmon_envsys * sme, envsys_data_t * edata)
+static int
+sht3x_parse_data(struct sht3x_sc *sc, envsys_data_t *edata, uint8_t *rawdata)
{
- struct sht3x_sc *sc;
- sc = sme->sme_cookie;
- int error;
- uint8_t rawdata[6];
- uint16_t measurement_command_ss;
uint64_t current_value;
uint8_t *svalptr;
- edata->state = ENVSYS_SINVALID;
-
- mutex_enter(&sc->sc_mutex);
-
- if (!sc->sc_isperiodic) {
- error = iic_acquire_bus(sc->sc_tag, 0);
- if (error) {
- DPRINTF(sc, 2, ("%s: Could not acquire i2c bus: %x\n",
- device_xname(sc->sc_dev), error));
- goto out;
- }
-
- measurement_command_ss = sht3x_compute_measure_command_ss(sc->sc_repeatability);
- DPRINTF(sc, 2, ("%s: Measurement command: %04x\n",
- device_xname(sc->sc_dev), measurement_command_ss));
- error = sht3x_cmdr(sc,measurement_command_ss,rawdata,6);
- if (error == 0) {
- DPRINTF(sc, 2, ("%s: Raw data ss: %02x%02x %02x - %02x%02x %02x\n",
- device_xname(sc->sc_dev), rawdata[0], rawdata[1], rawdata[2],
- rawdata[3], rawdata[4], rawdata[5]));
- switch (edata->sensor) {
- case SHT3X_TEMP_SENSOR:
- svalptr = &rawdata[0];
- current_value = sht3x_compute_temp_from_raw(rawdata[0],rawdata[1]);
- break;
- case SHT3X_HUMIDITY_SENSOR:
- svalptr = &rawdata[3];
- current_value = sht3x_compute_rh_from_raw(rawdata[3],rawdata[4]);
- break;
- default:
- error = EINTR;
- break;
- }
-
- if (error == 0) {
- uint8_t testcrc;
-
- /* Fake out the CRC check if being asked to ignore CRC */
- if (sc->sc_ignorecrc) {
- testcrc = *(svalptr + 2);
- } else {
- testcrc = sht3x_crc(svalptr,2);
- }
-
- if (*(svalptr + 2) == testcrc) {
- edata->value_cur = (uint32_t) current_value;
- edata->state = ENVSYS_SVALID;
- } else {
- error = EINVAL;
- }
- }
- }
-
- if (error) {
- DPRINTF(sc, 2, ("%s: Failed to get new status in refresh for single-shot %d\n",
- device_xname(sc->sc_dev), error));
- }
-
- uint16_t sbuf;
- int status_error;
-
- status_error = sht3x_get_status_register(sc, &sbuf, true);
-
- if (!status_error) {
- DPRINTF(sc, 2, ("%s: read status register single-shot: %04x\n",
- device_xname(sc->sc_dev), sbuf));
-
- if (sbuf & SHT3X_RESET_DETECTED) {
- aprint_error_dev(sc->sc_dev, "Reset detected in single shot mode. Heater may have been reset\n");
- sht3x_clear_status_register(sc, true);
- }
-
- sc->sc_heateron = sbuf & SHT3X_HEATER_STATUS;
- }
-
- iic_release_bus(sc->sc_tag, 0);
- } else {
- error = 0;
- memcpy(rawdata,sc->sc_pbuffer,6);
-
- DPRINTF(sc, 2, ("%s: Raw data periodic: %02x%02x %02x - %02x%02x %02x\n",
- device_xname(sc->sc_dev), rawdata[0], rawdata[1], rawdata[2],
- rawdata[3], rawdata[4], rawdata[5]));
-
- switch (edata->sensor) {
- case SHT3X_TEMP_SENSOR:
- svalptr = &rawdata[0];
- current_value = sht3x_compute_temp_from_raw(rawdata[0],rawdata[1]);
- break;
- case SHT3X_HUMIDITY_SENSOR:
- svalptr = &rawdata[3];
- current_value = sht3x_compute_rh_from_raw(rawdata[3],rawdata[4]);
- break;
- default:
- error = EINTR;
- break;
- }
-
- if (error == 0) {
- uint8_t testcrc;
-
- /* Fake out the CRC check if being asked to ignore CRC */
- if (sc->sc_ignorecrc) {
- testcrc = *(svalptr + 2);
- } else {
- testcrc = sht3x_crc(svalptr,2);
- }
-
- if (*(svalptr + 2) == testcrc) {
- edata->value_cur = (uint32_t) current_value;
- edata->state = ENVSYS_SVALID;
- } else {
- error = EINVAL;
- }
- }
-
- if (error) {
- DPRINTF(sc, 2, ("%s: Failed to get new status in refresh for periodic %d\n",
- device_xname(sc->sc_dev), error));
- }
- }
-out:
- mutex_exit(&sc->sc_mutex);
-}
-
-#ifdef __did_not_work
-static void
-sht3x_get_limits(struct sysmon_envsys *sme, envsys_data_t *edata,
- sysmon_envsys_lim_t *limits, uint32_t *props)
-{
- struct sht3x_sc *sc = sme->sme_cookie;
- uint16_t rawlimitshigh, rawlimitslow;
- uint16_t templimithigh, rhlimithigh,
- templimitlow, rhlimitlow;
- uint8_t templimithighmsb, templimithighlsb,
- templimitlowmsb, templimitlowlsb;
- uint8_t rhlimithighmsb, rhlimithighlsb,
- rhlimitlowmsb, rhlimitlowlsb;
- int error;
- uint8_t lbuf[3];
- uint8_t limitscrchigh, limitskcrchigh,
- limitscrclow, limitskcrclow;
-
- *props = 0;
-
- mutex_enter(&sc->sc_mutex);
- error = iic_acquire_bus(sc->sc_tag, 0);
- if (error) {
- DPRINTF(sc, 2, ("%s: Could not acquire i2c bus: %x\n",
- device_xname(sc->sc_dev), error));
- goto out;
- }
-
- error = sht3x_cmdr(sc, SHT3X_READ_HIGH_ALERT_SET, lbuf, 3);
- if (error) {
- DPRINTF(sc, 2, ("%s: Could not get high alert: %x\n",
- device_xname(sc->sc_dev), error));
- goto out;
- }
-
- rawlimitshigh = (lbuf[0] << 8) | lbuf[1];
- limitskcrchigh = lbuf[2];
- limitscrchigh = sht3x_crc(&lbuf[0],2);
-
- templimithigh = ((rawlimitshigh & 0x1FF) << 7);
- templimithighmsb = (uint8_t)(templimithigh >> 8);
- templimithighlsb = (uint8_t)(templimithigh & 0x00FF);
- DPRINTF(sc, 2, ("%s: Limits high intermediate temp: %04x %04x %02x %02x\n",
- device_xname(sc->sc_dev), rawlimitshigh, templimithigh, templimithighmsb,
- templimithighlsb));
-
- rhlimithigh = (rawlimitshigh & 0xFE00);
- rhlimithighmsb = (uint8_t)(rhlimithigh >> 8);
- rhlimithighlsb = (uint8_t)(rhlimithigh & 0x00FF);
- DPRINTF(sc, 2, ("%s: Limits high intermediate rh: %04x %04x %02x %02x\n",
- device_xname(sc->sc_dev), rawlimitshigh, rhlimithigh, rhlimithighmsb,
- rhlimithighlsb));
-
- DPRINTF(sc, 2, ("%s: Limit high raw: %02x%02x %02x %02x %02x\n",
- device_xname(sc->sc_dev), lbuf[0], lbuf[1], lbuf[2],
- limitscrchigh, limitskcrchigh));
-
- error = sht3x_cmdr(sc, SHT3X_READ_LOW_ALERT_SET, lbuf, 3);
- if (error) {
- DPRINTF(sc, 2, ("%s: Could not get high alert: %x\n",
- device_xname(sc->sc_dev), error));
- goto out;
- }
-
- rawlimitslow = (lbuf[0] << 8) | lbuf[1];
- limitskcrclow = lbuf[2];
- limitscrclow = sht3x_crc(&lbuf[0],2);
-
- templimitlow = ((rawlimitslow & 0x1FF) << 7);
- templimitlowmsb = (uint8_t)(templimitlow >> 8);
- templimitlowlsb = (uint8_t)(templimitlow & 0x00FF);
- DPRINTF(sc, 2, ("%s: Limits low intermediate temp: %04x %04x %02x %02x\n",
- device_xname(sc->sc_dev), rawlimitslow, templimitlow, templimitlowmsb,
- templimitlowlsb));
-
- rhlimitlow = (rawlimitslow & 0xFE00);
- rhlimitlowmsb = (uint8_t)(rhlimitlow >> 8);
- rhlimitlowlsb = (uint8_t)(rhlimitlow & 0x00FF);
- DPRINTF(sc, 2, ("%s: Limits low intermediate rh: %04x %04x %02x %02x\n",
- device_xname(sc->sc_dev), rawlimitslow, rhlimitlow, rhlimitlowmsb,
- rhlimitlowlsb));
-
- DPRINTF(sc, 2, ("%s: Limit low raw: %02x%02x %02x %02x %02x\n",
- device_xname(sc->sc_dev), lbuf[0], lbuf[1], lbuf[2],
- limitscrclow, limitskcrclow));
-
+ DPRINTF(sc, 2, ("%s: Raw data: %02x%02x %02x - %02x%02x %02x\n",
+ device_xname(sc->sc_dev), rawdata[0], rawdata[1], rawdata[2],
+ rawdata[3], rawdata[4], rawdata[5]));
switch (edata->sensor) {
case SHT3X_TEMP_SENSOR:
- if (limitscrchigh == limitskcrchigh) {
- limits->sel_critmax = sht3x_compute_temp_from_raw(templimithighmsb, templimithighlsb);
- *props |= PROP_CRITMAX;
- }
- if (limitscrclow == limitskcrclow) {
- limits->sel_critmin = sht3x_compute_temp_from_raw(templimitlowmsb, templimitlowlsb);
- *props |= PROP_CRITMIN;
- }
+ current_value = sht3x_compute_temp_from_raw(rawdata[0],
+ rawdata[1]);
+ svalptr = &rawdata[0];
break;
case SHT3X_HUMIDITY_SENSOR:
- if (limitscrchigh == limitskcrchigh) {
- limits->sel_critmax = sht3x_compute_rh_from_raw(rhlimithighmsb, rhlimithighlsb);
- *props |= PROP_CRITMAX;
- }
- if (limitscrclow == limitskcrclow) {
- limits->sel_critmin = sht3x_compute_rh_from_raw(rhlimitlowmsb, rhlimitlowlsb);
- *props |= PROP_CRITMIN;
- }
+ current_value = sht3x_compute_rh_from_raw(rawdata[3],
+ rawdata[4]);
+ svalptr = &rawdata[3];
break;
default:
- break;
- }
-
- if (*props != 0)
- *props |= PROP_DRIVER_LIMITS;
-
- iic_release_bus(sc->sc_tag, 0);
- out:
- mutex_exit(&sc->sc_mutex);
-}
-
-static void
-sht3x_set_alert_limits(void *aux, uint16_t high, uint16_t low, bool have_bus)
-{
- struct sht3x_sc *sc;
- sc = aux;
-
- int error = 0;
- uint8_t hbuf[3];
- uint8_t lbuf[3];
-
- if (! have_bus) {
- error = iic_acquire_bus(sc->sc_tag, 0);
- if (error) {
- DPRINTF(sc, 2, ("%s: Could not acquire iic bus for setting alerts %d\n",
- device_xname(sc->sc_dev), error));
- goto out;
- }
- }
-
- hbuf[0] = high >> 8;
- hbuf[1] = high & 0x00FF;
- hbuf[2] = sht3x_crc(&hbuf[0],2);
-
- lbuf[0] = low >> 8;
- lbuf[1] = low & 0x00FF;
- lbuf[2] = sht3x_crc(&lbuf[0],2);
-
- error = sht3x_cmdr(sc, SHT3X_WRITE_HIGH_ALERT_SET, hbuf, 3);
- if (error) {
- DPRINTF(sc, 2, ("%s: Could not set high alert for SET %d\n",
- device_xname(sc->sc_dev), error));
- goto out;
- }
- error = sht3x_cmdr(sc, SHT3X_WRITE_HIGH_ALERT_CLEAR, hbuf, 3);
- if (error) {
- DPRINTF(sc, 2, ("%s: Could not set high alert for CLEAR %d\n",
- device_xname(sc->sc_dev), error));
- goto out;
- }
- error = sht3x_cmdr(sc, SHT3X_WRITE_LOW_ALERT_SET, lbuf, 3);
- if (error) {
- DPRINTF(sc, 2, ("%s: Could not set low alert for SET %d\n",
- device_xname(sc->sc_dev), error));
- goto out;
- }
- error = sht3x_cmdr(sc, SHT3X_WRITE_LOW_ALERT_CLEAR, lbuf, 3);
- if (error) {
- DPRINTF(sc, 2, ("%s: Could not set high alert for CLEAR %d\n",
- device_xname(sc->sc_dev), error));
+ DPRINTF(sc, 2, ("%s: bad sensor type %d\n",
+ device_xname(sc->sc_dev), edata->sensor));
+ return EINTR;
+ }
+ uint8_t testcrc;
+ /* Fake out the CRC check if being asked to ignore CRC */
+ if (sc->sc_ignorecrc) {
+ testcrc = *(svalptr + 2);
+ } else {
+ testcrc = sht3x_crc(svalptr, 2);
}
- out:
- if (! have_bus) {
- iic_release_bus(sc->sc_tag, 0);
+ if (*(svalptr + 2) != testcrc) {
+ DPRINTF(sc, 2, ("%s: Failed to get new status in refresh %d != %d\n",
+ device_xname(sc->sc_dev), (*svalptr + 2), testcrc));
+ return EINVAL;
}
+ edata->value_cur = (uint32_t) current_value;
+ edata->state = ENVSYS_SVALID;
+ return 0;
}
-static void
-sht3x_set_alert_limits2(void *aux, uint16_t high, uint16_t low,
- uint16_t highminusone, uint16_t lowplusone, bool have_bus)
+static int
+sht3x_refresh_periodic(struct sysmon_envsys *sme, envsys_data_t *edata)
{
- struct sht3x_sc *sc;
- sc = aux;
-
- int error = 0;
- uint8_t hbuf[3];
- uint8_t lbuf[3];
- uint8_t hbufminusone[3];
- uint8_t lbufplusone[3];
-
- if (! have_bus) {
- error = iic_acquire_bus(sc->sc_tag, 0);
- if (error) {
- DPRINTF(sc, 2, ("%s: Could not acquire iic bus for setting alerts %d\n",
- device_xname(sc->sc_dev), error));
- goto out;
- }
- }
-
- hbuf[0] = high >> 8;
- hbuf[1] = high & 0x00FF;
- hbuf[2] = sht3x_crc(&hbuf[0],2);
-
- lbuf[0] = low >> 8;
- lbuf[1] = low & 0x00FF;
- lbuf[2] = sht3x_crc(&lbuf[0],2);
-
- hbufminusone[0] = highminusone >> 8;
- hbufminusone[1] = highminusone & 0x00FF;
- hbufminusone[2] = sht3x_crc(&hbufminusone[0],2);
-
- lbufplusone[0] = lowplusone >> 8;
- lbufplusone[1] = lowplusone & 0x00FF;
- lbufplusone[2] = sht3x_crc(&lbufplusone[0],2);
-
- DPRINTF(sc, 2, ("%s: Physical SET HIGH %02x %02x %02x\n",
- device_xname(sc->sc_dev), hbuf[0], hbuf[1], hbuf[2]));
- error = sht3x_cmdr(sc, SHT3X_WRITE_HIGH_ALERT_SET, hbuf, 3);
- if (error) {
- DPRINTF(sc, 2, ("%s: Could not set high alert for SET %d\n",
- device_xname(sc->sc_dev), error));
- goto out;
- }
-
- uint16_t sbuf;
- int status_error;
- status_error = sht3x_get_status_register(sc, &sbuf, true);
- DPRINTF(sc, 2, ("%s: In SETTING, status register %04x -- %d\n",
- device_xname(sc->sc_dev), sbuf, status_error));
-
- hbuf[0] = 0;
- hbuf[1] = 0;
- hbuf[2] = 0;
- error = sht3x_cmdr(sc, SHT3X_READ_HIGH_ALERT_SET, hbuf, 3);
- if (error) {
- DPRINTF(sc, 2, ("%s: Could not read high alert for SET %d\n",
- device_xname(sc->sc_dev), error));
- goto out;
- }
- DPRINTF(sc, 2, ("%s: Physical READBACK SET HIGH %02x %02x %02x\n",
- device_xname(sc->sc_dev), hbuf[0], hbuf[1], hbuf[2]));
+ struct sht3x_sc *sc = sme->sme_cookie;
+ uint8_t rawdata[sizeof(sc->sc_pbuffer)];
- DPRINTF(sc, 2, ("%s: Physical CLEAR HIGH %02x %02x %02x\n",
- device_xname(sc->sc_dev), hbufminusone[0], hbufminusone[1], hbufminusone[2]));
- error = sht3x_cmdr(sc, SHT3X_WRITE_HIGH_ALERT_CLEAR, hbufminusone, 3);
- if (error) {
- DPRINTF(sc, 2, ("%s: Could not set high alert for CLEAR %d\n",
- device_xname(sc->sc_dev), error));
- goto out;
- }
- hbufminusone[0] = 0;
- hbufminusone[1] = 0;
- hbufminusone[2] = 0;
- error = sht3x_cmdr(sc, SHT3X_READ_HIGH_ALERT_CLEAR, hbufminusone, 3);
- if (error) {
- DPRINTF(sc, 2, ("%s: Could not read high alert for CLEAR %d\n",
- device_xname(sc->sc_dev), error));
- goto out;
- }
- DPRINTF(sc, 2, ("%s: Physical READBACK CLEAR HIGH %02x %02x %02x\n",
- device_xname(sc->sc_dev), hbufminusone[0], hbufminusone[1], hbufminusone[2]));
+ memcpy(rawdata, sc->sc_pbuffer, sizeof(rawdata));
- DPRINTF(sc, 2, ("%s: Physical SET LOW %02x %02x %02x\n",
- device_xname(sc->sc_dev), lbuf[0], lbuf[1], lbuf[2]));
- error = sht3x_cmdr(sc, SHT3X_WRITE_LOW_ALERT_SET, lbuf, 3);
- if (error) {
- DPRINTF(sc, 2, ("%s: Could not set low alert for SET %d\n",
- device_xname(sc->sc_dev), error));
- goto out;
- }
- DPRINTF(sc, 2, ("%s: Physical CLEAR LOW %02x %02x %02x\n",
- device_xname(sc->sc_dev), lbufplusone[0], lbufplusone[1], lbufplusone[2]));
- error = sht3x_cmdr(sc, SHT3X_WRITE_LOW_ALERT_CLEAR, lbufplusone, 3);
- if (error) {
- DPRINTF(sc, 2, ("%s: Could not set high alert for CLEAR %d\n",
- device_xname(sc->sc_dev), error));
- }
+ return sht3x_parse_data(sc, edata, rawdata);
- out:
- if (! have_bus) {
- iic_release_bus(sc->sc_tag, 0);
- }
}
-static void
-sht3x_set_limits(struct sysmon_envsys *sme, envsys_data_t *edata,
- sysmon_envsys_lim_t *limits, uint32_t *props)
+static int
+sht3x_refresh_oneshot(struct sysmon_envsys *sme, envsys_data_t *edata)
{
struct sht3x_sc *sc = sme->sme_cookie;
- uint16_t rawlimitshigh, rawlimitslow;
- uint16_t rawlimitshighclear, rawlimitslowclear;
- uint16_t rawlimitshighminusone, rawlimitslowplusone;
+ uint16_t measurement_command_ss;
+ uint8_t rawdata[sizeof(sc->sc_pbuffer)];
int error;
- uint8_t lbuf[3];
- uint8_t limitscrchigh, limitskcrchigh,
- limitscrclow, limitskcrclow;
- uint16_t limithigh, limitlow;
- uint16_t limithighminusone, limitlowplusone;
- if (limits == NULL) {
- printf("XXX - Need to set back to default... limits is NULL\n");
- return;
- }
-
- DPRINTF(sc, 2, ("%s: In set_limits - %d -- %d %d\n",
- device_xname(sc->sc_dev), edata->sensor,
- limits->sel_critmin, limits->sel_critmax));
-
- mutex_enter(&sc->sc_mutex);
error = iic_acquire_bus(sc->sc_tag, 0);
if (error) {
DPRINTF(sc, 2, ("%s: Could not acquire i2c bus: %x\n",
device_xname(sc->sc_dev), error));
- goto out;
+ return error;
}
- error = sht3x_cmdr(sc, SHT3X_READ_HIGH_ALERT_SET, lbuf, 3);
- if (error) {
- DPRINTF(sc, 2, ("%s: Could not get high alert: %x\n",
- device_xname(sc->sc_dev), error));
- goto out;
+ measurement_command_ss = sht3x_compute_measure_command_ss(
+ sc->sc_repeatability);
+ DPRINTF(sc, 2, ("%s: Measurement command: %04x\n",
+ device_xname(sc->sc_dev), measurement_command_ss));
+ error = sht3x_cmdr(sc, measurement_command_ss, rawdata, sizeof(rawdata));
+ if (error == 0) {
+ DPRINTF(sc, 2, ("%s: Failed to get new status in refresh for "
+ "single-shot %d\n", device_xname(sc->sc_dev), error));
+ if ((error = sht3x_parse_data(sc, edata, rawdata)) == 0)
+ return 0;
}
- rawlimitshigh = (lbuf[0] << 8) | lbuf[1];
- limitskcrchigh = lbuf[2];
- limitscrchigh = sht3x_crc(&lbuf[0],2);
-
+ uint16_t sbuf;
+ int status_error = sht3x_get_status_register(sc, &sbuf, true);
- error = sht3x_cmdr(sc, SHT3X_READ_LOW_ALERT_SET, lbuf, 3);
- if (error) {
- DPRINTF(sc, 2, ("%s: Could not get high alert: %x\n",
- device_xname(sc->sc_dev), error));
- goto out;
- }
+ if (!status_error) {
+ DPRINTF(sc, 2, ("%s: read status register single-shot: %04x\n",
+ device_xname(sc->sc_dev), sbuf));
- rawlimitslow = (lbuf[0] << 8) | lbuf[1];
- limitskcrclow = lbuf[2];
- limitscrclow = sht3x_crc(&lbuf[0],2);
+ if (sbuf & SHT3X_RESET_DETECTED) {
+ aprint_error_dev(sc->sc_dev,
+ "Reset detected in single shot mode. "
+ "Heater may have been reset\n");
+ sht3x_clear_status_register(sc, true);
+ }
- error = sht3x_cmdr(sc, SHT3X_READ_HIGH_ALERT_CLEAR, lbuf, 3);
- if (error) {
- DPRINTF(sc, 2, ("%s: Could not get high alert clear: %x\n",
- device_xname(sc->sc_dev), error));
- goto out;
+ sc->sc_heateron = sbuf & SHT3X_HEATER_STATUS;
}
- rawlimitshighclear = (lbuf[0] << 8) | lbuf[1];
+ iic_release_bus(sc->sc_tag, 0);
+ return 0;
+}
- error = sht3x_cmdr(sc, SHT3X_READ_LOW_ALERT_CLEAR, lbuf, 3);
- if (error) {
- DPRINTF(sc, 2, ("%s: Could not get high alert clear: %x\n",
- device_xname(sc->sc_dev), error));
- goto out;
- }
+static void
+sht3x_refresh(struct sysmon_envsys *sme, envsys_data_t *edata)
+{
+ struct sht3x_sc *sc = sme->sme_cookie;
- rawlimitslowclear = (lbuf[0] << 8) | lbuf[1];
+ edata->state = ENVSYS_SINVALID;
- DPRINTF(sc, 2, ("%s: Set limits current raw limits %04x - %02x %02x ; %04x - %02x %02x ;; %04x %04x\n",
- device_xname(sc->sc_dev), rawlimitshigh, limitskcrchigh, limitscrchigh,
- rawlimitslow, limitskcrclow, limitscrclow, rawlimitshighclear, rawlimitslowclear));
+ mutex_enter(&sc->sc_mutex);
- switch (edata->sensor) {
- case SHT3X_TEMP_SENSOR:
- limithigh = sht3x_compute_raw_from_temp(limits->sel_critmax);
- limitlow = sht3x_compute_raw_from_temp(limits->sel_critmin);
- limithigh = limithigh >> 7;
- limithighminusone = limithigh - 1;
- limitlow = limitlow >> 7;
- limitlowplusone = limitlow + 1;
- rawlimitshigh = (rawlimitshigh & 0xFE00) | limithigh;
- rawlimitshighminusone = (rawlimitshigh & 0xFE00) | limithighminusone;
- rawlimitslow = (rawlimitslow & 0xFE00) | limitlow;
- rawlimitslowplusone = (rawlimitslow & 0xFE00) | limitlowplusone;
- DPRINTF(sc, 2, ("%s: Temp new raw limits high/low %04x %04x %04x %04x\n",
- device_xname(sc->sc_dev), rawlimitshigh, rawlimitslow,
- rawlimitshighminusone, rawlimitslowplusone));
- sht3x_set_alert_limits2(sc, rawlimitshigh, rawlimitslow,
- rawlimitshighminusone, rawlimitslowplusone, true);
- break;
- case SHT3X_HUMIDITY_SENSOR:
- limithigh = sht3x_compute_raw_from_rh(limits->sel_critmax);
- limitlow = sht3x_compute_raw_from_rh(limits->sel_critmin);
- limithigh = limithigh & 0xFE00;
- limitlow = limitlow & 0xFE00;
- rawlimitshigh = (rawlimitshigh & 0x1FF) | limithigh;
- rawlimitslow = (rawlimitslow & 0x1FF) | limitlow;
- DPRINTF(sc, 2, ("%s: RH new raw limits high/low %04x %04x from %x %x\n",
- device_xname(sc->sc_dev), rawlimitshigh, rawlimitslow, limithigh, limitlow));
- sht3x_set_alert_limits(sc, rawlimitshigh, rawlimitslow, true);
- break;
- default:
- break;
+ if (sc->sc_isperiodic) {
+ sht3x_refresh_periodic(sme, edata);
+ } else {
+ sht3x_refresh_oneshot(sme, edata);
}
- iic_release_bus(sc->sc_tag, 0);
- out:
mutex_exit(&sc->sc_mutex);
}
-#endif
static int
sht3xopen(dev_t dev, int flags, int fmt, struct lwp *l)
@@ -1875,10 +1433,10 @@ sht3xopen(dev_t dev, int flags, int fmt,
sc = device_lookup_private(&sht3xtemp_cd, minor(dev));
if (!sc)
- return (ENXIO);
+ return ENXIO;
if (sc->sc_opened)
- return (EBUSY);
+ return EBUSY;
mutex_enter(&sc->sc_mutex);
sc->sc_opened = true;
@@ -1893,7 +1451,7 @@ sht3xopen(dev_t dev, int flags, int fmt,
}
mutex_exit(&sc->sc_mutex);
- return (0);
+ return 0;
}
static int
@@ -1905,7 +1463,7 @@ sht3xread(dev_t dev, struct uio *uio, in
sc = device_lookup_private(&sht3xtemp_cd, minor(dev));
if (!sc)
- return (ENXIO);
+ return ENXIO;
while (uio->uio_resid) {
any = 0;
@@ -1918,23 +1476,29 @@ sht3xread(dev_t dev, struct uio *uio, in
SIMPLEQ_REMOVE_HEAD(&sc->sc_read_queue, read_q);
any = 1;
break;
- } else {
- error = cv_wait_sig(&sc->sc_condreadready,&sc->sc_read_mutex);
- if (sc->sc_dying)
- error = EIO;
- if (error == 0)
- continue;
- break;
}
+ error = cv_wait_sig(&sc->sc_condreadready,
+ &sc->sc_read_mutex);
+ if (sc->sc_dying)
+ error = EIO;
+ if (error == 0)
+ continue;
+ break;
}
if (any == 1 && error == 0) {
+ uint8_t *p = pp->measurement;
mutex_exit(&sc->sc_read_mutex);
pool_cache_put(sc->sc_readpool,pp);
- DPRINTF(sc,2, ("%s: sending %02x%02x %02x -- %02x%02x %02x -- %x\n",device_xname(sc->sc_dev),pp->measurement[0],pp->measurement[1],pp->measurement[2],pp->measurement[3],pp->measurement[4],pp->measurement[5],mutex_owned(&sc->sc_read_mutex)));
- if ((error = uiomove(&pp->measurement[0], 6, uio)) != 0) {
- DPRINTF(sc,2, ("%s: send error %d\n",device_xname(sc->sc_dev),error));
+ DPRINTF(sc,2, ("%s: sending %02x%02x %02x -- %02x%02x "
+ "%02x -- %x\n", device_xname(sc->sc_dev), p[0],
+ p[1], p[2], p[3], p[4], p[5],
+ mutex_owned(&sc->sc_read_mutex)));
+ if ((error = uiomove(pp->measurement,
+ sizeof(pp->measurement), uio)) != 0) {
+ DPRINTF(sc,2, ("%s: send error %d\n",
+ device_xname(sc->sc_dev), error));
break;
}
} else {
@@ -2009,7 +1573,8 @@ sht3x_detach(device_t self, int flags)
mutex_exit(&sc->sc_read_mutex);
DPRINTF(sc, 2, ("%s: Will wait for anything to exit\n",
device_xname(sc->sc_dev)));
- cv_timedwait_sig(&sc->sc_cond_dying,&sc->sc_dying_mutex,mstohz(5000));
+ cv_timedwait_sig(&sc->sc_cond_dying,
+ &sc->sc_dying_mutex, mstohz(5000));
mutex_exit(&sc->sc_dying_mutex);
cv_destroy(&sc->sc_condreadready);
cv_destroy(&sc->sc_cond_dying);