After testing with a couple of more samples of the SHT3x sensor chip

it was found that the datasheet does not appear to provide enough
information to make use of the alarm and interrupt function work.  So
actually remove the dead code that was an attempt at making that all
work.  Adjust the man page to mention that this.
This commit is contained in:
brad 2022-04-27 23:11:25 +00:00
parent dbdfee8ed1
commit 4e93751222
3 changed files with 13 additions and 468 deletions

View File

@ -1,4 +1,4 @@
.\" $NetBSD: sht3xtemp.4,v 1.2 2021/11/06 19:36:12 wiz Exp $
.\" $NetBSD: sht3xtemp.4,v 1.3 2022/04/27 23:11:25 brad Exp $
.\"
.\" Copyright (c) 2021 Brad Spencer <brad@anduin.eldar.org>
.\"
@ -119,3 +119,6 @@ The
.Nm
driver was written by
.An Brad Spencer Aq Mt brad@anduin.eldar.org .
.Sh BUGS
The datasheet did not provide enough information to get the alarm
function of the chip working.

View File

@ -1,5 +1,5 @@
/* $NetBSD: sht3x.c,v 1.6 2022/03/31 19:30:16 pgoyette Exp $ */
/* $NetBSD: sht3x.c,v 1.7 2022/04/27 23:11:25 brad Exp $ */
/*
* Copyright (c) 2021 Brad Spencer <brad@anduin.eldar.org>
@ -18,7 +18,7 @@
*/
#include <sys/cdefs.h>
__KERNEL_RCSID(0, "$NetBSD: sht3x.c,v 1.6 2022/03/31 19:30:16 pgoyette Exp $");
__KERNEL_RCSID(0, "$NetBSD: sht3x.c,v 1.7 2022/04/27 23:11:25 brad Exp $");
/*
Driver for the Sensirion SHT30/SHT31/SHT35
@ -52,18 +52,6 @@ static int sht3x_match(device_t, cfdata_t, void *);
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 *);
#ifdef __did_not_work
/*
* 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.
*/
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);
@ -1181,9 +1169,6 @@ sht3x_attach(device_t parent, device_t self, void *aux)
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));
@ -1200,10 +1185,6 @@ sht3x_attach(device_t parent, device_t self, void *aux)
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"));
@ -1370,38 +1351,6 @@ sht3x_parse_data(struct sht3x_sc *sc, envsys_data_t *edata, uint8_t *rawdata)
return 0;
}
#ifdef __did_not_work
/*
* 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.
*/
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 int
sht3x_refresh_periodic(struct sysmon_envsys *sme, envsys_data_t *edata)
{
@ -1478,419 +1427,6 @@ sht3x_refresh(struct sysmon_envsys *sme, envsys_data_t *edata)
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));
mutex_exit(&sc->sc_mutex);
return;
}
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));
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;
}
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;
}
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 = aux;
int error;
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));
return;
}
}
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));
}
out:
if (! have_bus) {
iic_release_bus(sc->sc_tag, 0);
}
}
static void
sht3x_set_alert_limits2(void *aux, uint16_t high, uint16_t low,
uint16_t highminusone, uint16_t lowplusone, bool have_bus)
{
struct sht3x_sc *sc;
sc = aux;
int error;
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));
return;
}
}
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]));
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]));
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));
}
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)
{
struct sht3x_sc *sc = sme->sme_cookie;
uint16_t rawlimitshigh, rawlimitslow;
uint16_t rawlimitshighclear, rawlimitslowclear;
uint16_t rawlimitshighminusone, rawlimitslowplusone;
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;
}
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);
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);
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;
}
rawlimitshighclear = (lbuf[0] << 8) | lbuf[1];
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;
}
rawlimitslowclear = (lbuf[0] << 8) | lbuf[1];
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));
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;
}
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)
{

View File

@ -1,4 +1,4 @@
/* $NetBSD: sht3xreg.h,v 1.1 2021/11/06 13:34:40 brad Exp $ */
/* $NetBSD: sht3xreg.h,v 1.2 2022/04/27 23:11:25 brad Exp $ */
/*
* Copyright (c) 2021 Brad Spencer <brad@anduin.eldar.org>
@ -80,6 +80,12 @@
#define SHT3X_WRITE_DATA_CHECKSUM 0x0001
/* Alert mode */
/* This is not supported by the sht3xtemp driver as
the information in the datasheet was not enough to
get it working. A read of the registers appears to
funtion just fine, but writes do not do anything, and
the chip does not indicate any errors occured.
*/
#define SHT3X_READ_HIGH_ALERT_SET 0xE11F
#define SHT3X_READ_HIGH_ALERT_CLEAR 0xE114
#define SHT3X_READ_LOW_ALERT_SET 0xE102