A driver for the Bosch BMP280 / BME280 temperature, humidity and

atmospheric pressure sensor.  This is an inexpensive to moderately
expensive chip available from a large number of places.  The driver
supports all aspects of the two chips, except for the repeating read
mode which would allow for sub-second queries, such as fall detection
or perhaps even as an altimeter.  This driver also only supports the
I2C interface and not the SPI interface.

The BME280, the one with humidity, is not fully tested at this point,
awaiting upon a breakout board and may not show proper humidity.
This commit is contained in:
brad 2022-11-21 21:24:00 +00:00
parent f202639d6b
commit 068b504f95
16 changed files with 1440 additions and 13 deletions

View File

@ -1,4 +1,4 @@
# $NetBSD: module.mi,v 1.21 2022/11/17 19:20:06 brad Exp $
# $NetBSD: module.mi,v 1.22 2022/11/21 21:24:01 brad Exp $
./usr/libdata/debug/@MODULEDIR@ modules-base-kernel kmod,debug
./usr/libdata/debug/@MODULEDIR@/accf_dataready modules-base-kernel kmod,debug
./usr/libdata/debug/@MODULEDIR@/accf_dataready/accf_dataready.kmod.debug modules-base-kernel kmod,debug
@ -22,6 +22,8 @@
./usr/libdata/debug/@MODULEDIR@/blake2s/blake2s.kmod.debug modules-base-kernel kmod,debug
./usr/libdata/debug/@MODULEDIR@/blowfish modules-base-kernel kmod,debug
./usr/libdata/debug/@MODULEDIR@/blowfish/blowfish.kmod.debug modules-base-kernel kmod,debug
./usr/libdata/debug/@MODULEDIR@/bmx280thp modules-base-kernel kmod,debug
./usr/libdata/debug/@MODULEDIR@/bmx280thp/bmx280thp.kmod.debug modules-base-kernel kmod,debug
./usr/libdata/debug/@MODULEDIR@/bpf modules-base-kernel kmod,debug
./usr/libdata/debug/@MODULEDIR@/bpf/bpf.kmod.debug modules-base-kernel kmod,debug
./usr/libdata/debug/@MODULEDIR@/bpf_filter modules-base-kernel kmod,debug

View File

@ -1,4 +1,4 @@
# $NetBSD: mi,v 1.1755 2022/11/17 19:20:06 brad Exp $
# $NetBSD: mi,v 1.1756 2022/11/21 21:24:01 brad Exp $
#
# Note: don't delete entries from here - mark them as "obsolete" instead.
#
@ -965,6 +965,7 @@
./usr/share/man/cat4/bio.0 man-sys-catman .cat
./usr/share/man/cat4/bktr.0 man-sys-catman .cat
./usr/share/man/cat4/bluetooth.0 man-sys-catman .cat
./usr/share/man/cat4/bmx280thp.0 man-sys-catman .cat
./usr/share/man/cat4/bmtphy.0 man-sys-catman .cat
./usr/share/man/cat4/bnx.0 man-sys-catman .cat
./usr/share/man/cat4/boca.0 man-sys-catman .cat
@ -4237,6 +4238,7 @@
./usr/share/man/html4/bio.html man-sys-htmlman html
./usr/share/man/html4/bktr.html man-sys-htmlman html
./usr/share/man/html4/bluetooth.html man-sys-htmlman html
./usr/share/man/html4/bmx280thp.html man-sys-htmlman html
./usr/share/man/html4/bmtphy.html man-sys-htmlman html
./usr/share/man/html4/bnx.html man-sys-htmlman html
./usr/share/man/html4/boca.html man-sys-htmlman html
@ -7275,6 +7277,7 @@
./usr/share/man/man4/bio.4 man-sys-man .man
./usr/share/man/man4/bktr.4 man-sys-man .man
./usr/share/man/man4/bluetooth.4 man-sys-man .man
./usr/share/man/man4/bmx280thp.4 man-sys-man .man
./usr/share/man/man4/bmtphy.4 man-sys-man .man
./usr/share/man/man4/bnx.4 man-sys-man .man
./usr/share/man/man4/boca.4 man-sys-man .man

View File

@ -1,4 +1,4 @@
# $NetBSD: mi,v 1.155 2022/11/17 19:20:06 brad Exp $
# $NetBSD: mi,v 1.156 2022/11/21 21:24:01 brad Exp $
#
# Note: don't delete entries from here - mark them as "obsolete" instead.
#
@ -31,6 +31,8 @@
./@MODULEDIR@/blake2s/blake2s.kmod modules-base-kernel kmod
./@MODULEDIR@/blowfish modules-base-kernel kmod
./@MODULEDIR@/blowfish/blowfish.kmod modules-base-kernel kmod
./@MODULEDIR@/bmx280thp modules-base-kernel kmod
./@MODULEDIR@/bmx280thp/bmx280thp.kmod modules-base-kernel kmod
./@MODULEDIR@/bpf modules-base-kernel kmod
./@MODULEDIR@/bpf/bpf.kmod modules-base-kernel kmod
./@MODULEDIR@/bpf_filter modules-base-kernel kmod

View File

@ -1,4 +1,4 @@
# $NetBSD: Makefile,v 1.729 2022/11/17 19:20:05 brad Exp $
# $NetBSD: Makefile,v 1.730 2022/11/21 21:24:00 brad Exp $
# @(#)Makefile 8.1 (Berkeley) 6/18/93
MAN= aac.4 ac97.4 acardide.4 aceride.4 acphy.4 \
@ -11,7 +11,7 @@ MAN= aac.4 ac97.4 acardide.4 aceride.4 acphy.4 \
auacer.4 audio.4 audiocs.4 auich.4 \
auixp.4 autri.4 auvia.4 awi.4 \
battery_pmu.4 bba.4 bce.4 bcsp.4 be.4 bge.4 bnx.4 bha.4 \
bio.4 bktr.4 bluetooth.4 bmtphy.4 bpf.4 bpfjit.4 \
bio.4 bktr.4 bluetooth.4 bmx280thp.4 bmtphy.4 bpf.4 bpfjit.4 \
brgphy.4 bridge.4 bthidev.4 bthub.4 btkbd.4 \
btmagic.4 btms.4 btsco.4 btuart.4 \
bwfm.4 bwi.4 \

View File

@ -0,0 +1,89 @@
.\" $NetBSD: bmx280thp.4,v 1.1 2022/11/21 21:24:00 brad Exp $
.\"
.\" Copyright (c) 2022 Brad Spencer <brad@anduin.eldar.org>
.\"
.\" 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 November 19, 2022
.Dt BMX280THP 4
.Os
.Sh NAME
.Nm bmx280thp
.Nd Driver for Bosch BMP280/BME280 sensor chip via I2C bus
.Sh SYNOPSIS
.Cd "bmx280thp* at iic? addr 0x76"
.Cd "bmx280thp* at iic? addr 0x77"
.Sh DESCRIPTION
The
.Nm
driver provides measurements from the BMP280 and BME280 temperature,
humidity and barometric pressure sensors via the
.Xr envsys 4
framework.
The
.Nm
.Ar addr
argument selects the address at the
.Xr iic 4
bus.
The percision of the measurement can be changed through
.Xr sysctl 8
nodes.
.Sh SYSCTL VARIABLES
The following
.Xr sysctl 3
variables are provided:
.Bl -tag -width indent
.It Li hw.bmx280thp0.osrs_t
.It Li hw.bmx280thp0.osrs_p
.It Li hw.bmx280thp0.osrs_h
These control oversampling of temperature, pressure and humidity. The
valid values are 1, 2, 4, 8, and 16 times oversample. Humidity is only
available if the chip is a BME280.
.It Li hw.bmx280thp0.irr_samples
IRR is a filter that can be used to reduce the noise in the
measurement. The value values are 1 (or off), 2, 5, 11 and 22 samples
to reach >= 75% of the step response.
.It Li hw.bmx280thp0.debug
.It Li hw.bmx280thp0.dump_calibration
If the driver is compiled with
.Dv BMX280_DEBUG ,
these nodes will appear and can be used to set the debugging level and
provide the calibration constants, upon refresh, that are stored in the
chip. Since the constants are fixed, this is a boolean node and will
reset back to false once one dump has been performed.
.It Li hw.bmx280thp0.readattempts
A status register tells the driver if the chip is busy with a measurement.
This status register must be polled and readattempts is the number of times
that this poll will be performed.
The default is 25 which should be more than enough for most purposes.
.El
.Sh SEE ALSO
.Xr envsys 4 ,
.Xr iic 4 ,
.Xr envstat 8 ,
.Xr sysctl 8
.Sh HISTORY
The
.Nm
driver first appeared in
.Nx 10.0 .
.Sh AUTHORS
.An -nosplit
The
.Nm
driver was written by
.An Brad Spencer Aq Mt brad@anduin.eldar.org .
.Sh BUGS
The driver does not support the continuous read mode that the BMP280
and BME280 has. This driver does not support the SPI interface.

1074
sys/dev/i2c/bmx280.c Normal file

File diff suppressed because it is too large Load Diff

96
sys/dev/i2c/bmx280reg.h Normal file
View File

@ -0,0 +1,96 @@
/* $NetBSD: bmx280reg.h,v 1.1 2022/11/21 21:24:01 brad Exp $ */
/*
* Copyright (c) 2022 Brad Spencer <brad@anduin.eldar.org>
*
* 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.
*/
#ifndef _DEV_I2C_BMX280REG_H_
#define _DEV_I2C_BMX280REG_H_
#define BMX280_TYPICAL_ADDR_1 0x76
#define BMX280_TYPICAL_ADDR_2 0x77
#define BMX280_REGISTER_DIG_T1 0x88
#define BMX280_REGISTER_DIG_T2 0x8A
#define BMX280_REGISTER_DIG_T3 0x8C
#define BMX280_REGISTER_DIG_P1 0x8E
#define BMX280_REGISTER_DIG_P2 0x90
#define BMX280_REGISTER_DIG_P3 0x92
#define BMX280_REGISTER_DIG_P4 0x94
#define BMX280_REGISTER_DIG_P5 0x96
#define BMX280_REGISTER_DIG_P6 0x98
#define BMX280_REGISTER_DIG_P7 0x9A
#define BMX280_REGISTER_DIG_P8 0x9C
#define BMX280_REGISTER_DIG_P9 0x9E
#define BMX280_REGISTER_DIG_H1 0xA1
#define BMX280_REGISTER_DIG_H2 0xE1
#define BMX280_REGISTER_DIG_H3 0xE3
#define BMX280_REGISTER_DIG_H4 0xE4
#define BMX280_REGISTER_DIG_H5 0xE5
#define BMX280_REGISTER_ID 0xD0
#define BMX280_ID_BMP280 0x58
#define BMX280_ID_BME280 0x60
#define BMX280_REGISTER_RESET 0xE0
#define BMX280_TRIGGER_RESET 0xB6
#define BMX280_REGISTER_CTRL_HUM 0xF2
#define BMX280_REGISTER_STATUS 0xF3
#define BMX280_STATUS_MEASURING_MASK 0x08
#define BMX280_STATUS_IM_UPDATE_MASK 0x01
#define BMX280_REGISTER_CTRL_MEAS 0xF4
#define BMX280_CTRL_OSRS_T_MASK 0xE0
#define BMX280_CTRL_OSRS_P_MASK 0x1C
#define BMX280_CTRL_OSRS_T_SHIFT 5
#define BMX280_CTRL_OSRS_P_SHIFT 2
#define BMX280_OSRS_TP_VALUE_SKIPPED 0x00
#define BMX280_OSRS_TP_VALUE_X1 0x01
#define BMX280_OSRS_TP_VALUE_X2 0x02
#define BMX280_OSRS_TP_VALUE_X4 0x03
#define BMX280_OSRS_TP_VALUE_X8 0x04
#define BMX280_OSRS_TP_VALUE_X16 0x05
#define BMX280_CTRL_MODE_MASK 0x03
#define BMX280_MODE_SLEEP 0x00
#define BMX280_MODE_FORCED 0x01
#define BMX280_MODE_NORMAL 0x03
#define BMX280_REGISTER_CONFIG 0xF5
#define BMX280_CONFIG_T_SB_MASK 0xE0
#define BMX280_CONFIG_FILTER_MASK 0x1C
#define BMX280_CONFIG_FILTER_SHIFT 2
#define BMX280_FILTER_VALUE_OFF 0x00
#define BMX280_FILTER_VALUE_2 0x01
#define BMX280_FILTER_VALUE_5 0x02
#define BMX280_FILTER_VALUE_11 0x04
#define BMX280_FILTER_VALUE_22 0x05
#define BMX280_CONFIG_SPI3W_EN_MASK 0x01
#define BMX280_REGISTER_PRESS_MSB 0xF7
#define BMX280_REGISTER_PRESS_LSB 0xF8
#define BMX280_REGISTER_PRESS_XLSB 0xF9
#define BMX280_REGISTER_TEMP_MSB 0xFA
#define BMX280_REGISTER_TEMP_LSB 0xFB
#define BMX280_REGISTER_TEMP_XLSB 0xFC
#define BMX280_TEMPPRES_XLSB_MASK 0xF0
#define BMX280_REGISTER_HUM_MSB 0xFD
#define BMX280_REGISTER_HUM_LSB 0xFE
#endif

85
sys/dev/i2c/bmx280var.h Normal file
View File

@ -0,0 +1,85 @@
/* $NetBSD: bmx280var.h,v 1.1 2022/11/21 21:24:01 brad Exp $ */
/*
* Copyright (c) 2022 Brad Spencer <brad@anduin.eldar.org>
*
* 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.
*/
#ifndef _DEV_I2C_BMX280VAR_H_
#define _DEV_I2C_BMX280VAR_H_
#define BMX280_NUM_SENSORS 3
#define BMX280_TEMP_SENSOR 0
#define BMX280_PRESSURE_SENSOR 1
#define BMX280_HUMIDITY_SENSOR 2
struct bmx280_calibration_blob {
uint16_t dig_T1;
int16_t dig_T2;
int16_t dig_T3;
uint16_t dig_P1;
int16_t dig_P2;
int16_t dig_P3;
int16_t dig_P4;
int16_t dig_P5;
int16_t dig_P6;
int16_t dig_P7;
int16_t dig_P8;
int16_t dig_P9;
uint8_t dig_H1;
int16_t dig_H2;
uint8_t dig_H3;
int16_t dig_H4;
int16_t dig_H5;
int8_t dig_H6;
};
struct bmx280_sc {
int sc_bmx280debug;
device_t sc_dev;
i2c_tag_t sc_tag;
i2c_addr_t sc_addr;
kmutex_t sc_mutex;
int sc_numsensors;
struct sysmon_envsys *sc_sme;
struct sysctllog *sc_bmx280log;
envsys_data_t sc_sensors[BMX280_NUM_SENSORS];
struct bmx280_calibration_blob sc_cal_blob;
bool sc_has_humidity;
int sc_readattempts;
int sc_osrs_t;
int sc_osrs_p;
int sc_osrs_h;
int sc_irr_samples;
uint8_t sc_previous_irr;
bool sc_bmx280dump;
};
struct bmx280_sensor {
const char *desc;
enum envsys_units type;
};
struct bmx280_osrs_list {
const int text;
uint8_t mask;
};
struct bmx280_irr_list {
const int text;
uint8_t mask;
};
#endif

View File

@ -1,4 +1,4 @@
# $NetBSD: files.i2c,v 1.124 2022/11/17 19:20:06 brad Exp $
# $NetBSD: files.i2c,v 1.125 2022/11/21 21:24:01 brad Exp $
obsolete defflag opt_i2cbus.h I2C_SCAN
define i2cbus { }
@ -435,3 +435,8 @@ file dev/i2c/scmdi2c.c scmdi2c
device aht20temp
attach aht20temp at iic
file dev/i2c/aht20.c aht20temp
# Bosch Sensortec BMP280/BME280 Temperature, Humidity and Pressure sensor
device bmx280thp
attach bmx280thp at iic
file dev/i2c/bmx280.c bmx280thp

View File

@ -1,4 +1,4 @@
/* $NetBSD: sysmon_envsys_tables.c,v 1.13 2018/05/27 01:39:00 thorpej Exp $ */
/* $NetBSD: sysmon_envsys_tables.c,v 1.14 2022/11/21 21:24:01 brad Exp $ */
/*-
* Copyright (c) 2007 Juan Romero Pardines.
@ -26,7 +26,7 @@
*/
#include <sys/cdefs.h>
__KERNEL_RCSID(0, "$NetBSD: sysmon_envsys_tables.c,v 1.13 2018/05/27 01:39:00 thorpej Exp $");
__KERNEL_RCSID(0, "$NetBSD: sysmon_envsys_tables.c,v 1.14 2022/11/21 21:24:01 brad Exp $");
#include <sys/types.h>
@ -53,6 +53,7 @@ static const struct sme_descr_entry sme_units_description[] = {
{ ENVSYS_BATTERY_CHARGE, -1, "Battery charge" },
{ ENVSYS_SRELHUMIDITY, -1, "relative Humidity" },
{ ENVSYS_LUX, -1, "Illuminance" },
{ ENVSYS_PRESSURE, -1, "pressure" },
{ -1, -1, "unknown" }
};

View File

@ -1,4 +1,4 @@
# $NetBSD: Makefile,v 1.272 2022/11/17 19:20:05 brad Exp $
# $NetBSD: Makefile,v 1.273 2022/11/21 21:24:01 brad Exp $
.include <bsd.own.mk>
@ -33,6 +33,7 @@ SUBDIR+= blake2s
SUBDIR+= blowfish
SUBDIR+= bpf
SUBDIR+= bpf_filter
SUBDIR+= bmx280thp
SUBDIR+= bufq_disksort
SUBDIR+= bufq_fcfs
SUBDIR+= bufq_priocscan

View File

@ -0,0 +1,11 @@
.include "../Makefile.inc"
.PATH: ${S}/dev/i2c
KMOD= bmx280thp
IOCONF= bmx280thp.ioconf
SRCS= bmx280.c
WARNS= 3
.include <bsd.kmodule.mk>

View File

@ -0,0 +1,8 @@
ioconf bmx280thp
include "conf/files"
pseudo-root iic*
bmx280thp* at iic? addr 0x76
bmx280thp* at iic? addr 0x77

View File

@ -1,4 +1,4 @@
/* $NetBSD: envsys.h,v 1.38 2018/05/27 06:40:31 wiz Exp $ */
/* $NetBSD: envsys.h,v 1.39 2022/11/21 21:24:01 brad Exp $ */
/*-
* Copyright (c) 1999, 2007, 2014 The NetBSD Foundation, Inc.
@ -65,6 +65,7 @@ enum envsys_units {
ENVSYS_BATTERY_CHARGE, /* Battery charging/discharging */
ENVSYS_SRELHUMIDITY, /* relative humidity */
ENVSYS_LUX, /* illuminance in lux */
ENVSYS_PRESSURE, /* pressure in hPa */
ENVSYS_NSENSORS
};

View File

@ -1,4 +1,4 @@
.\" $NetBSD: envstat.8,v 1.66 2020/11/14 20:07:13 wiz Exp $
.\" $NetBSD: envstat.8,v 1.67 2022/11/21 21:24:02 brad Exp $
.\"
.\" Copyright (c) 2000, 2007, 2008, 2009, 2014 The NetBSD Foundation, Inc.
.\" All rights reserved.
@ -190,6 +190,8 @@ Watts
Watt-hours
.It %rH
relative Humidity
.It hPa
Hectopascals
.El
.Sh EXAMPLES
To display the

View File

@ -1,4 +1,4 @@
/* $NetBSD: envstat.c,v 1.102 2022/05/28 10:36:24 andvar Exp $ */
/* $NetBSD: envstat.c,v 1.103 2022/11/21 21:24:02 brad Exp $ */
/*-
* Copyright (c) 2007, 2008 Juan Romero Pardines.
@ -27,7 +27,7 @@
#include <sys/cdefs.h>
#ifndef lint
__RCSID("$NetBSD: envstat.c,v 1.102 2022/05/28 10:36:24 andvar Exp $");
__RCSID("$NetBSD: envstat.c,v 1.103 2022/11/21 21:24:02 brad Exp $");
#endif /* not lint */
#include <stdio.h>
@ -1174,6 +1174,53 @@ do { \
if (!nflag)
(void)printf(" %*s", (int)ilen - 3, stype);
/* Pressure */
} else if (strcmp(sensor->type, "pressure") == 0) {
stype = "hPa";
(void)printf("%s%*.3f", sep, flen,
sensor->cur_value / 10000.0);
ilen = 8;
if (statistics) {
/* show statistics if flag set */
(void)printf(" %.3f %.3f %.3f",
stats->max / 10000.0, stats->min / 10000.0, stats->avg / 10000.0);
ilen += 2;
} else if (!nflag) {
if (sensor->critmax_value) {
(void)printf(" %*u", (int)ilen,
sensor->critmax_value);
ilen = 8;
} else
ilen += 9;
if (sensor->warnmax_value) {
(void)printf(" %*u", (int)ilen,
sensor->warnmax_value);
ilen = 8;
} else
ilen += 9;
if (sensor->warnmin_value) {
(void)printf(" %*u", (int)ilen,
sensor->warnmin_value);
ilen = 8;
} else
ilen += 9;
if (sensor->critmin_value) {
(void)printf( " %*u", (int)ilen,
sensor->critmin_value);
ilen = 8;
} else
ilen += 9;
}
if (!nflag)
(void)printf(" %*s", (int)ilen - 3, stype);
/* everything else */
} else {
if (strcmp(sensor->type, "Voltage DC") == 0)