1 /* 2 * Copyright (c) 2016, 2017 Intel Corporation 3 * Copyright (c) 2017 IpTronix S.r.l. 4 * Copyright (c) 2021 Nordic Semiconductor ASA 5 * 6 * SPDX-License-Identifier: Apache-2.0 7 */ 8 9 #ifndef ZEPHYR_DRIVERS_SENSOR_BME280_BME280_H_ 10 #define ZEPHYR_DRIVERS_SENSOR_BME280_BME280_H_ 11 12 #include <zephyr/types.h> 13 #include <zephyr/device.h> 14 #include <zephyr/devicetree.h> 15 #include <zephyr/drivers/spi.h> 16 #include <zephyr/drivers/i2c.h> 17 #include <zephyr/drivers/sensor.h> 18 #include <zephyr/rtio/rtio.h> 19 20 #define DT_DRV_COMPAT bosch_bme280 21 22 #define BME280_BUS_SPI DT_ANY_INST_ON_BUS_STATUS_OKAY(spi) 23 #define BME280_BUS_I2C DT_ANY_INST_ON_BUS_STATUS_OKAY(i2c) 24 25 union bme280_bus { 26 #if BME280_BUS_SPI 27 struct spi_dt_spec spi; 28 #endif 29 #if BME280_BUS_I2C 30 struct i2c_dt_spec i2c; 31 #endif 32 }; 33 34 typedef int (*bme280_bus_check_fn)(const union bme280_bus *bus); 35 typedef int (*bme280_reg_read_fn)(const union bme280_bus *bus, uint8_t start, uint8_t *buf, 36 int size); 37 typedef int (*bme280_reg_write_fn)(const union bme280_bus *bus, uint8_t reg, uint8_t val); 38 39 struct bme280_bus_io { 40 bme280_bus_check_fn check; 41 bme280_reg_read_fn read; 42 bme280_reg_write_fn write; 43 }; 44 45 #if BME280_BUS_SPI 46 #define BME280_SPI_OPERATION (SPI_WORD_SET(8) | SPI_TRANSFER_MSB | SPI_MODE_CPOL | SPI_MODE_CPHA) 47 extern const struct bme280_bus_io bme280_bus_io_spi; 48 #endif 49 50 #if BME280_BUS_I2C 51 extern const struct bme280_bus_io bme280_bus_io_i2c; 52 #endif 53 54 #define BME280_REG_PRESS_MSB 0xF7 55 #define BME280_REG_COMP_START 0x88 56 #define BME280_REG_HUM_COMP_PART1 0xA1 57 #define BME280_REG_HUM_COMP_PART2 0xE1 58 #define BME280_REG_ID 0xD0 59 #define BME280_REG_CONFIG 0xF5 60 #define BME280_REG_CTRL_MEAS 0xF4 61 #define BME280_REG_CTRL_HUM 0xF2 62 #define BME280_REG_STATUS 0xF3 63 #define BME280_REG_RESET 0xE0 64 65 #define BMP280_CHIP_ID_SAMPLE_1 0x56 66 #define BMP280_CHIP_ID_SAMPLE_2 0x57 67 #define BMP280_CHIP_ID_MP 0x58 68 #define BME280_CHIP_ID 0x60 69 #define BME280_MODE_SLEEP 0x00 70 #define BME280_MODE_FORCED 0x01 71 #define BME280_MODE_NORMAL 0x03 72 #define BME280_SPI_3W_DISABLE 0x00 73 #define BME280_CMD_SOFT_RESET 0xB6 74 #define BME280_STATUS_MEASURING 0x08 75 #define BME280_STATUS_IM_UPDATE 0x01 76 77 #if defined CONFIG_BME280_MODE_NORMAL 78 #define BME280_MODE BME280_MODE_NORMAL 79 #elif defined CONFIG_BME280_MODE_FORCED 80 #define BME280_MODE BME280_MODE_FORCED 81 #endif 82 83 #if defined CONFIG_BME280_TEMP_OVER_1X 84 #define BME280_TEMP_OVER (1 << 5) 85 #elif defined CONFIG_BME280_TEMP_OVER_2X 86 #define BME280_TEMP_OVER (2 << 5) 87 #elif defined CONFIG_BME280_TEMP_OVER_4X 88 #define BME280_TEMP_OVER (3 << 5) 89 #elif defined CONFIG_BME280_TEMP_OVER_8X 90 #define BME280_TEMP_OVER (4 << 5) 91 #elif defined CONFIG_BME280_TEMP_OVER_16X 92 #define BME280_TEMP_OVER (5 << 5) 93 #endif 94 95 #if defined CONFIG_BME280_PRESS_OVER_1X 96 #define BME280_PRESS_OVER (1 << 2) 97 #elif defined CONFIG_BME280_PRESS_OVER_2X 98 #define BME280_PRESS_OVER (2 << 2) 99 #elif defined CONFIG_BME280_PRESS_OVER_4X 100 #define BME280_PRESS_OVER (3 << 2) 101 #elif defined CONFIG_BME280_PRESS_OVER_8X 102 #define BME280_PRESS_OVER (4 << 2) 103 #elif defined CONFIG_BME280_PRESS_OVER_16X 104 #define BME280_PRESS_OVER (5 << 2) 105 #endif 106 107 #if defined CONFIG_BME280_HUMIDITY_OVER_1X 108 #define BME280_HUMIDITY_OVER 1 109 #elif defined CONFIG_BME280_HUMIDITY_OVER_2X 110 #define BME280_HUMIDITY_OVER 2 111 #elif defined CONFIG_BME280_HUMIDITY_OVER_4X 112 #define BME280_HUMIDITY_OVER 3 113 #elif defined CONFIG_BME280_HUMIDITY_OVER_8X 114 #define BME280_HUMIDITY_OVER 4 115 #elif defined CONFIG_BME280_HUMIDITY_OVER_16X 116 #define BME280_HUMIDITY_OVER 5 117 #endif 118 119 #if defined CONFIG_BME280_STANDBY_05MS 120 #define BME280_STANDBY 0 121 #elif defined CONFIG_BME280_STANDBY_62MS 122 #define BME280_STANDBY (1 << 5) 123 #elif defined CONFIG_BME280_STANDBY_125MS 124 #define BME280_STANDBY (2 << 5) 125 #elif defined CONFIG_BME280_STANDBY_250MS 126 #define BME280_STANDBY (3 << 5) 127 #elif defined CONFIG_BME280_STANDBY_500MS 128 #define BME280_STANDBY (4 << 5) 129 #elif defined CONFIG_BME280_STANDBY_1000MS 130 #define BME280_STANDBY (5 << 5) 131 #elif defined CONFIG_BME280_STANDBY_2000MS 132 #define BME280_STANDBY (6 << 5) 133 #elif defined CONFIG_BME280_STANDBY_4000MS 134 #define BME280_STANDBY (7 << 5) 135 #endif 136 137 #if defined CONFIG_BME280_FILTER_OFF 138 #define BME280_FILTER 0 139 #elif defined CONFIG_BME280_FILTER_2 140 #define BME280_FILTER (1 << 2) 141 #elif defined CONFIG_BME280_FILTER_4 142 #define BME280_FILTER (2 << 2) 143 #elif defined CONFIG_BME280_FILTER_8 144 #define BME280_FILTER (3 << 2) 145 #elif defined CONFIG_BME280_FILTER_16 146 #define BME280_FILTER (4 << 2) 147 #endif 148 149 #define BME280_CTRL_MEAS_VAL (BME280_PRESS_OVER | BME280_TEMP_OVER | BME280_MODE) 150 #define BME280_CONFIG_VAL (BME280_STANDBY | BME280_FILTER | BME280_SPI_3W_DISABLE) 151 152 #define BME280_CTRL_MEAS_OFF_VAL (BME280_PRESS_OVER | BME280_TEMP_OVER | BME280_MODE_SLEEP) 153 154 /* Convert to Q15.16 */ 155 #define BME280_TEMP_CONV 100 156 #define BME280_TEMP_SHIFT 16 157 /* Treat UQ24.8 as Q23.8 158 * Need to divide by 1000 to convert to kPa 159 */ 160 #define BME280_PRESS_CONV_KPA 1000 161 #define BME280_PRESS_SHIFT 23 162 /* Treat UQ22.10 as Q21.10 */ 163 #define BME280_HUM_SHIFT 21 164 165 struct bme280_reading { 166 /* Compensated values. */ 167 int32_t comp_temp; 168 uint32_t comp_press; 169 uint32_t comp_humidity; 170 }; 171 172 struct bme280_data { 173 /* Compensation parameters. */ 174 uint16_t dig_t1; 175 int16_t dig_t2; 176 int16_t dig_t3; 177 uint16_t dig_p1; 178 int16_t dig_p2; 179 int16_t dig_p3; 180 int16_t dig_p4; 181 int16_t dig_p5; 182 int16_t dig_p6; 183 int16_t dig_p7; 184 int16_t dig_p8; 185 int16_t dig_p9; 186 uint8_t dig_h1; 187 int16_t dig_h2; 188 uint8_t dig_h3; 189 int16_t dig_h4; 190 int16_t dig_h5; 191 int8_t dig_h6; 192 193 /* Carryover between temperature and pressure/humidity compensation. */ 194 int32_t t_fine; 195 196 uint8_t chip_id; 197 198 struct bme280_reading reading; 199 }; 200 201 /* 202 * RTIO 203 */ 204 205 struct bme280_decoder_header { 206 uint64_t timestamp; 207 } __attribute__((__packed__)); 208 209 struct bme280_encoded_data { 210 struct bme280_decoder_header header; 211 struct { 212 /** Set if `temp` has data */ 213 uint8_t has_temp: 1; 214 /** Set if `press` has data */ 215 uint8_t has_press: 1; 216 /** Set if `humidity` has data */ 217 uint8_t has_humidity: 1; 218 } __attribute__((__packed__)); 219 struct bme280_reading reading; 220 }; 221 222 int bme280_get_decoder(const struct device *dev, const struct sensor_decoder_api **decoder); 223 224 void bme280_submit(const struct device *dev, struct rtio_iodev_sqe *iodev_sqe); 225 226 int bme280_sample_fetch(const struct device *dev, enum sensor_channel chan); 227 228 int bme280_sample_fetch_helper(const struct device *dev, enum sensor_channel chan, 229 struct bme280_reading *reading); 230 231 #endif /* ZEPHYR_DRIVERS_SENSOR_BME280_BME280_H_ */ 232