Yes this works. >From dmesg:
sxitwi0 at simplebus0 iic0 at sxitwi0 bme0 at iic0 addr 0x76: BME280 60 sxitwi1 at simplebus0 iic1 at sxitwi1 bme1 at iic1 addr 0x77: BME280 60 And from sysctl: op1bsdsnap# sysctl hw.sensors hw.sensors.sxitemp0.temp0=187.74 degC (CPU) hw.sensors.bme0.temp0=22.95 degC hw.sensors.bme0.humidity0=52.01% hw.sensors.bme0.pressure0=101.36 Pa hw.sensors.bme1.temp0=24.02 degC hw.sensors.bme1.humidity0=47.54% hw.sensors.bme1.pressure0=101.33 Pa op1bsdsnap# sysctl hw.sensors hw.sensors.sxitemp0.temp0=187.74 degC (CPU) hw.sensors.bme0.temp0=22.84 degC hw.sensors.bme0.humidity0=52.32% hw.sensors.bme0.pressure0=101.36 Pa hw.sensors.bme1.temp0=24.01 degC hw.sensors.bme1.humidity0=47.54% hw.sensors.bme1.pressure0=101.34 Pa The " hw.sensors.sxitemp0.temp0=187.74 degC (CPU)" will be the topic in another conversation. I have added h3 to the sxitemp driver, but I can not get the hardware to provide a reading. -----Original Message----- From: aa e30 <artturi....@gmail.com> Sent: May 7, 2018 2:27 PM To: s_g...@telus.net Subject: Re: new bme code On 8 May 2018 at 00:25, <s_g...@telus.net> wrote: > Would you please send me the diff as an attachment. The inline has > some lines wrapped and the diff does not apply cleanly. > > -----Original Message----- > From: Artturi Alm <artturi....@gmail.com> > Sent: May 6, 2018 3:05 AM > To: s_g...@telus.net > Cc: arm@openbsd.org > Subject: Re: gtk libool slow on arm > > On Thu, May 03, 2018 at 09:55:21PM -0700, s_g...@telus.net wrote: >> Thank you for the updates. I will build and test as soon as I get > finished with the php build. My system is still flailing away at gtk > with each ld session taking about 20 minutes. Could be days yet. >> > > fixed the diff with moving dev/fdt/bme.c to dev/i2c/bme280.c, thanks > to clue by kettenis@. > > -Artturi > > > diff --git share/man/man4/Makefile share/man/man4/Makefile index > 8004d8b575d..3ac02b89788 100644 > --- share/man/man4/Makefile > +++ share/man/man4/Makefile > @@ -15,7 +15,7 @@ MAN= aac.4 ac97.4 acphy.4 acrtc.4 \ > auacer.4 audio.4 aue.4 auglx.4 auich.4 auixp.4 autri.4 auvia.4 \ > axe.4 axen.4 axppmic.4 azalia.4 \ > bce.4 bcmaux.4 bcmdog.4 bcmrng.4 bcmtemp.4 berkwdt.4 bge.4 \ > - bgw.4 bio.4 bktr.4 bmtphy.4 bnx.4 \ > + bgw.4 bio.4 bktr.4 bme.4 bmtphy.4 bnx.4 \ > boca.4 bpf.4 brgphy.4 bridge.4 brswphy.4 bwfm.4 bwi.4 bytgpio.4 \ > cac.4 cas.4 cardbus.4 carp.4 ccp.4 cd.4 cdce.4 cfxga.4 \ > ch.4 chvgpio.4 ciphy.4 ciss.4 clcs.4 clct.4 cmpci.4 \ diff > --git > share/man/man4/bme.4 share/man/man4/bme.4 new file mode 100644 index > 00000000000..bb48513d9dc > --- /dev/null > +++ share/man/man4/bme.4 > @@ -0,0 +1,44 @@ > +.\" $OpenBSD: tsl.4,v 1.10 2015/10/02 09:29:02 sobrado Exp $ > +.\" > +.\" Copyright (c) 2005 Mark Kettenis <kette...@openbsd.org> .\" > +Copyright (c) 2018 Artturi Alm .\" > +.\" Permission to use, copy, modify, and distribute this software for > +any .\" purpose with or without fee is hereby granted, provided that > +the above .\" copyright notice and this permission notice appear in > +all > copies. > +.\" > +.\" THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL > +WARRANTIES .\" WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED > +WARRANTIES OF .\" MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE > +AUTHOR BE LIABLE FOR .\" ANY SPECIAL, DIRECT, INDIRECT, OR > +CONSEQUENTIAL DAMAGES OR ANY DAMAGES .\" WHATSOEVER RESULTING FROM > +LOSS OF USE, DATA OR PROFITS, WHETHER IN AN .\" ACTION OF CONTRACT, > +NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF .\" OR IN > +CONNECTION > WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. > +.\" > +.Dd $Mdocdate$ > +.Dt BME 4 > +.Os > +.Sh NAME > +.Nm bme > +.Nd Bosch BME280 Environmental sensor .Sh SYNOPSIS .Cd "bme* at iic?" > +.Sh DESCRIPTION > +The > +.Nm > +driver provides support for the Bosch BME280 Environmental sensor. > +These sensors contain combined digital humidity, pressure and > +temperature sensing capabilities. > +These values are made available through the .Xr sysctl 8 interface. > +.Sh SEE ALSO > +.Xr iic 4 , > +.Xr intro 4 , > +.Xr sensorsd 8 , > +.Xr sysctl 8 > +.Sh HISTORY > +The > +.Nm > +driver first appeared in > +.Ox 6.4 . > diff --git sys/dev/i2c/bme280.c sys/dev/i2c/bme280.c new file mode > 100644 index 00000000000..8d35f5ae44d > --- /dev/null > +++ sys/dev/i2c/bme280.c > @@ -0,0 +1,543 @@ > +/* $OpenBSD: tsl2560.c,v 1.7 2008/04/18 01:17:51 deraadt Exp $ */ > + > +/* > + * Copyright (c) 2005 Mark Kettenis > + * Copyright (c) 2017 Artturi Alm > + * > + * Permission to use, copy, modify, and distribute this software for > +any > + * purpose with or without fee is hereby granted, provided that the > +above > + * copyright notice and this permission notice appear in all copies. > + * > + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL > +WARRANTIES > + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF > + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE > +LIABLE FOR > + * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY > +DAMAGES > + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN > +AN > + * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING > +OUT OF > + * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. > + */ > + > +#include <sys/param.h> > +#include <sys/systm.h> > +#include <sys/device.h> > +#include <sys/kthread.h> > +#include <sys/sensors.h> > + > +#include <dev/i2c/i2cvar.h> > + > +/* > + * Register Name Address b7 b6 b5 b4 b3 b2 b1 b0 Reset state > + * hum_lsb 0xFE hum_lsb<7:0> 0x00 > + * hum_msb 0xFD hum_msb<7:0> 0x80 > + * temp_xlsb 0xFC temp_xlsb<7:4> 0000 0x00 > + * temp_lsb 0xFB temp_lsb<7:0> 0x00 > + * temp_msb 0xFA temp_msb<7:0> 0x80 > + * press_xlsb 0xF9 press_xlsb<7:4> 0000 0x00 > + * press_lsb 0xF8 press_lsb<7:0> 0x00 > + * press_msb 0xF7 press_msb<7:0> 0x80 > + * config 0xF5 t_sb[2:0]filter[2:0]spi3w_en[0] 0x00 > + * ctrl_meas 0xF4 osrs_p[2:0]osrs_t[2:0]mode[1:0] 0x00 > + * status 0xF3 measuring[0]im_update[0] 0x00 > + * ctrl_hum 0xF2 osrs_h[2:0] 0x00 > + * calib26..calib41 0xE1-0xF0 calibration data individual > + * reset 0xE0 reset[7:0] 0x00 > + * id 0xD0 chip_id[7:0] 0x60 > + * calib00..calib25 0x88-0xA1 calibration data individual > +*/ > + > +#define BME280_CALIB00_23 0x88 > +#define BME280_CALIB24 0xa1 > +#define BME280_ID 0xd0 > +#define BME280_RESET 0xe0 > + /* soft reset magic value */ > +#define BME280_RESET_MAGIC 0xb6 > +#define BME280_CALIB25_31 0xe1 > + /* changes become effective only after a write op to ctrl_meas */ > +#define BME280_CTRL_HUM 0xf2 > + > +#define BME280_STATUS 0xf3 > +#define BME280_STATUS_MASK 0x09 > +#define BME280_STATUS_CONV 0x08 /* conversion running */ > +#define BME280_STATUS_UPD 0x01 /* update in progress */ > + > +#define BME280_CTRL_MEAS 0xf4 > +#define BME280_CTRL_MEAS_MODE_MASK 0x03 > +#define BME280_CTRL_MEAS_MODE_SLEEP 0x00 > +#define BME280_CTRL_MEAS_MODE_FORCED 0x01 > +#define BME280_CTRL_MEAS_MODE_FORCE 0x02 > +#define BME280_CTRL_MEAS_MODE_NORMAL 0x03 > + /* writes in normal mode may be ignored, not so in sleep mode */ > +#define BME280_CONFIG 0xf5 > +#define BME280_CONFIG_SPI_EN 0x01 > + > +#define BME280_PRESS_MSB 0xf7 > +#define BME280_PRESS_LSB 0xf8 > +#define BME280_PRESS_XLSB 0xf9 > +#define BME280_TEMP_MSB 0xfa > +#define BME280_TEMP_LSB 0xfb > +#define BME280_TEMP_XLSB 0xfc > +#define BME280_HUM_MSB 0xfd > +#define BME280_HUM_LSB 0xfe > + > +#define BME_OVERSAMPLING_SKIP 0x00 > +#define BME_OVERSAMPLING_X1 0x01 > +#define BME_OVERSAMPLING_X2 0x02 > +#define BME_OVERSAMPLING_X4 0x03 > +#define BME_OVERSAMPLING_X8 0x04 > +#define BME_OVERSAMPLING_X16 0x05 > + > +#define BME_HUMI 0 > +#define BME_TEMP 1 > +#define BME_PRES 2 > + > +struct bme_softc { > + struct device sc_dev; > + i2c_tag_t sc_i2c; > + i2c_addr_t sc_addr; > + > + struct ksensor sc_sensor[3]; > + struct ksensordev sc_sensordev; > + > + int sc_calibrated; > + int sc_configured; > + > + /* > + * fine resolution temperature value for pressure and > + * humidity compensation formulas. > + */ > + int32_t sc_t_fine; > + /* calibration data */ > + int32_t sc_t_trim[3]; > + int64_t sc_p_trim[9]; > + int32_t sc_h_trim[6]; > +}; > + > +int bme_match(struct device *, void *, void *); > +void bme_attach(struct device *, struct device *, void *); > +void bme_deferred(void *); > +void bme_refresh(void *); > +void bme_softreset(struct bme_softc *, int); > +void bme_configure(struct bme_softc *, int); > +void bme_get_calib(struct bme_softc *, int); > + > +int32_t bme_comp_temp(struct bme_softc *, int32_t); > +uint32_t bme_comp_pres(struct bme_softc *, int32_t); > +uint32_t bme_comp_humi(struct bme_softc *, int32_t); > + > +static inline uint8_t bme_config_filter(int); static inline uint8_t > +bme_config_standby(int); static inline uint8_t > +bme_oversample(uint8_t, uint8_t); > + > +struct cfattach bme_ca = { > + sizeof(struct bme_softc), bme_match, bme_attach }; > + > +struct cfdriver bme_cd = { > + NULL, "bme", DV_DULL > +}; > + > +int > +bme_match(struct device *parent, void *match, void *aux) { > + struct i2c_attach_args *ia = aux; > + > + if (strcmp(ia->ia_name, "bosch,bme280") == 0) > + return 1; > + > + return 0; > +} > + > +void > +bme_attach(struct device *parent, struct device *self, void *aux) { > + struct bme_softc *sc = (struct bme_softc *)self; > + struct i2c_attach_args *ia = aux; > + int ieflags = I2C_F_POLL; > + uint8_t reg_addr, data; > + > + sc->sc_i2c = ia->ia_tag; > + sc->sc_addr = ia->ia_addr; > + > + iic_acquire_bus(sc->sc_i2c, ieflags); > + > + sc->sc_calibrated = 0; > + bme_softreset(sc, ieflags); > + > + reg_addr = BME280_ID; > + if (iic_exec(sc->sc_i2c, I2C_OP_READ_WITH_STOP, > + sc->sc_addr, ®_addr, 1, &data, 1, ieflags)) { > + iic_release_bus(sc->sc_i2c, ieflags); > + printf(": failed to read ID register\n"); > + return; > + } > + > + iic_release_bus(sc->sc_i2c, ieflags); > + > + switch (data) { > + default: > + printf(": unknown value in ID register 0x%x\n", data); > + return; > + case 0x58: > + case 0x57: > + case 0x56: > + /* XXX atleast somehow register compatible with BMP280 */ > + printf(": sorry, no BMP280 support yet\n"); > + return; > + case 0x60: > + printf(": BME280 %x\n", data); > + break; > + } > + > + kthread_create_deferred(bme_deferred, sc); } > + > +void > +bme_deferred(void *arg) > +{ > + struct bme_softc *sc = arg; > + int ieflags = I2C_F_POLL; /* XXX cold ? I2C_F_POLL : 0 */ > + int i; > + > + iic_acquire_bus(sc->sc_i2c, ieflags); > + > + bme_configure(sc, ieflags); > +#ifdef DIAGNOSTIC > + if (sc->sc_configured != 1) /* non-fatal */ > + printf("%s: failed to configure\n", > +sc->sc_dev.dv_xname); > #endif > + > + bme_get_calib(sc, ieflags); > + > + iic_release_bus(sc->sc_i2c, ieflags); > + > + if (sc->sc_calibrated != 1) { > + printf("%s: failed to read calibration data\n", > + sc->sc_dev.dv_xname); > + /* fatal; and retrying feels bloat, fix your i2c "wiring" */ > + return; /* XXX can't defer failure to config_detach.. :( */ > + } > + > + if (sensor_task_register(sc, bme_refresh, 1) == NULL) { > + printf("%s: unable to register update task\n", > + sc->sc_dev.dv_xname); > + return; > + } > + > + /* Initialize sensor data. */ > + strlcpy(sc->sc_sensordev.xname, sc->sc_dev.dv_xname, > + sizeof(sc->sc_sensordev.xname)); > + sc->sc_sensor[BME_HUMI].type = SENSOR_HUMIDITY; > + sc->sc_sensor[BME_TEMP].type = SENSOR_TEMP; > + sc->sc_sensor[BME_PRES].type = SENSOR_PRESSURE; > + > + for (i = 0; i < 3; i++) { > + sc->sc_sensor[i].flags = SENSOR_FINVALID; > + sensor_attach(&sc->sc_sensordev, &sc->sc_sensor[i]); > + } > + sensordev_install(&sc->sc_sensordev); > +} > + > +void > +bme_refresh(void *arg) > +{ > + struct bme_softc *sc = arg; > + int32_t raw[3] = { 0, 0, 0 }; > + int ieflags = I2C_F_POLL; /* XXX cold ? I2C_F_POLL : 0 */ > + uint8_t addr; > + uint8_t data[8]; > + > + iic_acquire_bus(sc->sc_i2c, ieflags); > + > + if (sc->sc_configured == 0) { > + bme_configure(sc, ieflags); > + if (sc->sc_configured != 1) { #ifdef DIAGNOSTIC > + printf("%s: failed to configure - resetting\n", > + sc->sc_dev.dv_xname); #endif > + bme_softreset(sc, ieflags); > + goto fail_out; > + } > + } > + > + /* > + * read raw uncompensated values in a single read "burst", > + * to keep data register shadowing functional in the normal-mode > + * we're configured to, as we don't really synchronize with the > + * sensor, so we have no need to read the status register at all. > + */ > + addr = BME280_PRESS_MSB; > + if (iic_exec(sc->sc_i2c, I2C_OP_READ_WITH_STOP, > + sc->sc_addr, &addr, 1, &data, sizeof data, ieflags)) { > + printf("%s: failed to read data - resetting\n", > + sc->sc_dev.dv_xname); > + bme_softreset(sc, ieflags); > + bme_configure(sc, ieflags); > + goto fail_out; > + } > + > + iic_release_bus(sc->sc_i2c, ieflags); > + > + /* got raw */ > + raw[BME_HUMI] = (data[6] << 8) | data[7]; > + raw[BME_TEMP] = (data[3] << 12) | (data[4] << 4) | (data[5] >> 4); > + raw[BME_PRES] = (data[0] << 12) | (data[1] << 4) | (data[2] >> > + 4); > + > + /* do compensate raw values */ > + sc->sc_sensor[BME_TEMP].value = bme_comp_temp(sc, raw[BME_TEMP]); > + sc->sc_sensor[BME_PRES].value = bme_comp_pres(sc, raw[BME_PRES]); > + sc->sc_sensor[BME_HUMI].value = bme_comp_humi(sc, > + raw[BME_HUMI]); > + > + sc->sc_sensor[BME_TEMP].flags &= ~SENSOR_FINVALID; > + sc->sc_sensor[BME_PRES].flags &= ~SENSOR_FINVALID; > + sc->sc_sensor[BME_HUMI].flags &= ~SENSOR_FINVALID; > + return; > +fail_out: > + iic_release_bus(sc->sc_i2c, ieflags); > + sc->sc_sensor[BME_TEMP].flags |= SENSOR_FINVALID; > + sc->sc_sensor[BME_PRES].flags |= SENSOR_FINVALID; > + sc->sc_sensor[BME_HUMI].flags |= SENSOR_FINVALID; } > + > +void > +bme_get_calib(struct bme_softc *sc, int ieflags) { > + int i, j; > + uint8_t addr; > + uint8_t calib[32]; > + > + /* read calibration data */ > + addr = BME280_CALIB00_23; > + if (iic_exec(sc->sc_i2c, I2C_OP_READ_WITH_STOP, > + sc->sc_addr, &addr, 1, &calib[0], 24, ieflags)) > + return; > + > + addr = BME280_CALIB24; > + if (iic_exec(sc->sc_i2c, I2C_OP_READ_WITH_STOP, > + sc->sc_addr, &addr, 1, &calib[24], 1, ieflags)) > + return; > + > + addr = BME280_CALIB25_31; > + if (iic_exec(sc->sc_i2c, I2C_OP_READ_WITH_STOP, > + sc->sc_addr, &addr, 1, &calib[25], 7, ieflags)) > + return; > + > + /* adjust calibration data for later compensations */ > + for (i = 0, j = 0; i < 3; j += 2) > + sc->sc_t_trim[i++] = (calib[j + 1] << 8) | calib[j]; > + for (i = 0, j = 6; i < 9; j += 2) > + sc->sc_p_trim[i++] = (calib[j + 1] << 8) | calib[j]; > + sc->sc_h_trim[(i = 0)] = calib[24]; > + sc->sc_h_trim[++i] = (calib[26] << 8) | calib[25]; > + sc->sc_h_trim[++i] = calib[27]; > + sc->sc_h_trim[++i] = (calib[28] << 4) | (calib[29] & 0xf); > + sc->sc_h_trim[++i] = (calib[30] << 4) | ((calib[29] & 0xf0) >> 4); > + sc->sc_h_trim[++i] = calib[31]; > + > + for (i = 1; i < 3; i++) > + if (sc->sc_t_trim[i] & 0x8000) > + sc->sc_t_trim[i] = (-sc->sc_t_trim[i] ^ 0xffff) + 1; > + for (j = 1; j < 9; j++) > + if (sc->sc_p_trim[j] & 0x8000) > + sc->sc_p_trim[j] = (-sc->sc_p_trim[j] ^ 0xffff) + 1; > + for (i = 1; i < 6; i++) /* XXX last one is signed char? */ > + if (sc->sc_h_trim[i] & 0x8000) /* so will never match > + this > */ > + sc->sc_h_trim[i] = (-sc->sc_h_trim[i] ^ > + 0xffff) + 1; > + > + sc->sc_calibrated = 1; > +} > + > +/* > + * this is not really required, as the chip should be in this > + * condition already after Power-On-Reset (POR), and we configure > + * everything without reading current values in correct order, > + * so i decided to let this fail as void, trusting sc_configured=0 > +will > + * fix configuration registers later anyway. > + */ > +void > +bme_softreset(struct bme_softc *sc, int ieflags) { > + uint8_t addr = BME280_RESET; > + uint8_t data = BME280_RESET_MAGIC; > + > + sc->sc_configured = 0; > + > + if (iic_exec(sc->sc_i2c, I2C_OP_WRITE_WITH_STOP, > + sc->sc_addr, &addr, 1, &data, 1, ieflags)) { #ifdef > +DIAGNOSTIC > + printf("%s: failed to write softreset\n", > sc->sc_dev.dv_xname); > +#endif > + return; > + } > + /* > + * XXX should this have some delay here? SoC-performance do vary.. > + */ > +} > + > +void > +bme_configure(struct bme_softc *sc, int ieflags) { > + uint8_t addr, data; > + > + /* XXX do seek for devicetree bindings, for config parameters > + */ > + > + addr = BME280_CTRL_HUM; > + data = bme_oversample(1, BME_HUMI); > + if (iic_exec(sc->sc_i2c, I2C_OP_WRITE_WITH_STOP, > + sc->sc_addr, &addr, 1, &data, 1, ieflags)) > + return; > + > + addr = BME280_CONFIG; > + data = bme_config_filter(0) | bme_config_standby(1000000); > + if (iic_exec(sc->sc_i2c, I2C_OP_WRITE_WITH_STOP, > + sc->sc_addr, &addr, 1, &data, 1, ieflags)) > + return; > + > + addr = BME280_CTRL_MEAS; > + data = BME280_CTRL_MEAS_MODE_NORMAL | bme_oversample(1, BME_TEMP) | > + bme_oversample(1, BME_PRES); > + if (iic_exec(sc->sc_i2c, I2C_OP_WRITE_WITH_STOP, > + sc->sc_addr, &addr, 1, &data, 1, ieflags)) > + return; > + > + sc->sc_configured = 1; > +} > + > +int32_t > +bme_comp_temp(struct bme_softc *sc, int32_t raw) { > + int32_t t1 = sc->sc_t_trim[0]; > + int32_t t2 = sc->sc_t_trim[1]; > + int32_t t3 = sc->sc_t_trim[2]; > + int32_t var1 = ((((raw >> 3) - (t1 << 1))) * t2) >> 11; > + int32_t var2 = (((((raw >> 4) - t1) * ((raw >> 4) - t1)) >> > +12) * > t3) > + >> 14; > + int32_t rv_t; > + > + sc->sc_t_fine = var1 + var2; > + rv_t = (sc->sc_t_fine * 5 + 128) >> 8; > + rv_t = (rv_t + 27315) * 10000; /* for micro Kelvin */ > + return rv_t; > +} > + > +uint32_t > +bme_comp_pres(struct bme_softc *sc, int32_t raw) { > + int64_t var1 = (int64_t)sc->sc_t_fine; > + int64_t var2; > + int64_t pa; > + > + var1 -= 128000; > + var2 = var1 * var1 * sc->sc_p_trim[5]; > + var2 = var2 + ((var1 * sc->sc_p_trim[4]) << 17); > + var2 = var2 + (sc->sc_p_trim[3] << 35); > + > + var1 = ((var1 * var1 * sc->sc_p_trim[2]) >> 8) + > + ((var1 * sc->sc_p_trim[1]) << 12); > + > + var1 = ((((int64_t)1) << 47) + var1) * sc->sc_p_trim[0] >> 33; > + if (var1 == 0) > + return 0; > + > + pa = 1048576 - raw; > + pa = (((pa << 31) - var2) * 3125) / var1; > + var1 = (sc->sc_p_trim[8] * (pa >> 13) * (pa >> 13)) >> 25; > + var2 = (sc->sc_p_trim[7] * pa) >> 19; > + pa = ((pa + var1 + var2) >> 8) + (sc->sc_p_trim[6] << 4); > + pa /= 256; > + return (uint32_t)pa; > +} > + > +uint32_t > +bme_comp_humi(struct bme_softc *sc, int32_t raw) { > + int32_t rh = (int32_t)sc->sc_t_fine; > + > + rh -= 76800; > + rh = (((((raw << 14) - (sc->sc_h_trim[3] << 20) - > + (sc->sc_h_trim[4] * rh)) + 16384) >> 15) * > + (((((((rh * sc->sc_h_trim[5]) >> 10) * > + (((rh * sc->sc_h_trim[2]) >> 11) + 32768)) >> 10) + > + 2097152) * sc->sc_h_trim[1] + 8192) >> 14)); > + rh -= (((((rh >> 15) * (rh >> 15)) >> 7) * sc->sc_h_trim[0]) >> 4); > + if (rh < 0) > + rh = 0; > + if (rh > 419430400) > + rh = 419430400; > + rh >>= 12; > + rh = (rh * 1000) / 1024; > + return (uint32_t)rh; > +} > + > +uint8_t > +bme_config_filter(int filter_coeff) > +{ > + switch (filter_coeff) { > + default: > + case 0: /* filter off */ > + return 0x00; > + case 2: > + return 0x01; > + case 4: > + return 0x02; > + case 8: > + return 0x03; > + case 16: > + return 0x04; > + } > +} > + > +uint8_t > +bme_config_standby(int us) > +{ > + switch (us) { > + case 500: > + return 0x00U << 5; > + case 10000: > + return 0x06U << 5; > + case 20000: > + return 0x07U << 5; > + case 62500: > + return 0x01U << 5; > + case 125000: > + return 0x02U << 5; > + case 250000: > + return 0x03U << 5; > + case 500000: > + return 0x04U << 5; > + default: > + case 1000000: > + return 0x05U << 5; > + } > +} > + > +uint8_t > +bme_oversample(uint8_t over_sample, uint8_t sensor) { > + uint8_t off = 0; > + > + switch (sensor) { > + case BME_PRES: > + off += 3; > + case BME_TEMP: > + off += 2; > + case BME_HUMI: > + break; > + default: > + return 0; > + } > + > + switch (over_sample) { > + default: > + case 0: > + return BME_OVERSAMPLING_SKIP; > + case 1: > + return BME_OVERSAMPLING_X1 << off; > + case 2: > + return BME_OVERSAMPLING_X2 << off; > + case 4: > + return BME_OVERSAMPLING_X4 << off; > + case 16: > + return BME_OVERSAMPLING_X16 << off; > + } > +} > diff --git sys/dev/i2c/files.i2c sys/dev/i2c/files.i2c index > 10f5bc63fa8..edb070bd11a 100644 > --- sys/dev/i2c/files.i2c > +++ sys/dev/i2c/files.i2c > @@ -220,6 +220,11 @@ device bgw > attach bgw at i2c > file dev/i2c/bmc150.c bgw > > +# Bosch BME280 environmental sensor > +device bme > +attach bme at i2c > +file dev/i2c/bme280.c bme > + > # Intersil ISL1208 Real Time Clock > device islrtc > attach islrtc at i2c > diff --git sys/arch/armv7/conf/GENERIC sys/arch/armv7/conf/GENERIC > index > 052f73bf71f..59d314e5909 100644 > --- sys/arch/armv7/conf/GENERIC > +++ sys/arch/armv7/conf/GENERIC > @@ -179,6 +179,7 @@ rktemp* at fdt? > dwdog* at fdt? > > axppmic* at iic? # axp209 pmic > +bme* at iic? # BME280 environmental sensor > crosec* at iic? > wskbd* at crosec? mux 1 > pcfrtc* at iic? >