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 #define BME280_TEMP_SAMPLE_TIME 2 86 #elif defined CONFIG_BME280_TEMP_OVER_2X 87 #define BME280_TEMP_OVER (2 << 5) 88 #define BME280_TEMP_SAMPLE_TIME 4 89 #elif defined CONFIG_BME280_TEMP_OVER_4X 90 #define BME280_TEMP_OVER (3 << 5) 91 #define BME280_TEMP_SAMPLE_TIME 8 92 #elif defined CONFIG_BME280_TEMP_OVER_8X 93 #define BME280_TEMP_OVER (4 << 5) 94 #define BME280_TEMP_SAMPLE_TIME 16 95 #elif defined CONFIG_BME280_TEMP_OVER_16X 96 #define BME280_TEMP_OVER (5 << 5) 97 #define BME280_TEMP_SAMPLE_TIME 32 98 #endif 99 100 #if defined CONFIG_BME280_PRESS_OVER_1X 101 #define BME280_PRESS_OVER (1 << 2) 102 #define BME280_PRESS_SAMPLE_TIME 2 103 #elif defined CONFIG_BME280_PRESS_OVER_2X 104 #define BME280_PRESS_OVER (2 << 2) 105 #define BME280_PRESS_SAMPLE_TIME 4 106 #elif defined CONFIG_BME280_PRESS_OVER_4X 107 #define BME280_PRESS_OVER (3 << 2) 108 #define BME280_PRESS_SAMPLE_TIME 8 109 #elif defined CONFIG_BME280_PRESS_OVER_8X 110 #define BME280_PRESS_OVER (4 << 2) 111 #define BME280_PRESS_SAMPLE_TIME 16 112 #elif defined CONFIG_BME280_PRESS_OVER_16X 113 #define BME280_PRESS_OVER (5 << 2) 114 #define BME280_PRESS_SAMPLE_TIME 32 115 #endif 116 117 #if defined CONFIG_BME280_HUMIDITY_OVER_1X 118 #define BME280_HUMIDITY_OVER 1 119 #define BME280_HUMIDITY_SAMPLE_TIME 2 120 #elif defined CONFIG_BME280_HUMIDITY_OVER_2X 121 #define BME280_HUMIDITY_OVER 2 122 #define BME280_HUMIDITY_SAMPLE_TIME 4 123 #elif defined CONFIG_BME280_HUMIDITY_OVER_4X 124 #define BME280_HUMIDITY_OVER 3 125 #define BME280_HUMIDITY_SAMPLE_TIME 8 126 #elif defined CONFIG_BME280_HUMIDITY_OVER_8X 127 #define BME280_HUMIDITY_OVER 4 128 #define BME280_HUMIDITY_SAMPLE_TIME 16 129 #elif defined CONFIG_BME280_HUMIDITY_OVER_16X 130 #define BME280_HUMIDITY_OVER 5 131 #define BME280_HUMIDITY_SAMPLE_TIME 32 132 #endif 133 134 #if defined CONFIG_BME280_STANDBY_05MS 135 #define BME280_STANDBY 0 136 #elif defined CONFIG_BME280_STANDBY_62MS 137 #define BME280_STANDBY (1 << 5) 138 #elif defined CONFIG_BME280_STANDBY_125MS 139 #define BME280_STANDBY (2 << 5) 140 #elif defined CONFIG_BME280_STANDBY_250MS 141 #define BME280_STANDBY (3 << 5) 142 #elif defined CONFIG_BME280_STANDBY_500MS 143 #define BME280_STANDBY (4 << 5) 144 #elif defined CONFIG_BME280_STANDBY_1000MS 145 #define BME280_STANDBY (5 << 5) 146 #elif defined CONFIG_BME280_STANDBY_2000MS 147 #define BME280_STANDBY (6 << 5) 148 #elif defined CONFIG_BME280_STANDBY_4000MS 149 #define BME280_STANDBY (7 << 5) 150 #endif 151 152 #if defined CONFIG_BME280_FILTER_OFF 153 #define BME280_FILTER 0 154 #elif defined CONFIG_BME280_FILTER_2 155 #define BME280_FILTER (1 << 2) 156 #elif defined CONFIG_BME280_FILTER_4 157 #define BME280_FILTER (2 << 2) 158 #elif defined CONFIG_BME280_FILTER_8 159 #define BME280_FILTER (3 << 2) 160 #elif defined CONFIG_BME280_FILTER_16 161 #define BME280_FILTER (4 << 2) 162 #endif 163 164 #define BME280_CTRL_MEAS_VAL (BME280_PRESS_OVER | BME280_TEMP_OVER | BME280_MODE) 165 #define BME280_CONFIG_VAL (BME280_STANDBY | BME280_FILTER | BME280_SPI_3W_DISABLE) 166 167 #define BME280_CTRL_MEAS_OFF_VAL (BME280_PRESS_OVER | BME280_TEMP_OVER | BME280_MODE_SLEEP) 168 169 /* Convert to Q15.16 */ 170 #define BME280_TEMP_CONV 100 171 #define BME280_TEMP_SHIFT 16 172 /* Treat UQ24.8 as Q23.8 173 * Need to divide by 1000 to convert to kPa 174 */ 175 #define BME280_PRESS_CONV_KPA 1000 176 #define BME280_PRESS_SHIFT 23 177 /* Treat UQ22.10 as Q21.10 */ 178 #define BME280_HUM_SHIFT 21 179 180 struct bme280_reading { 181 /* Compensated values. */ 182 int32_t comp_temp; 183 uint32_t comp_press; 184 uint32_t comp_humidity; 185 }; 186 187 struct bme280_data { 188 /* Compensation parameters. */ 189 uint16_t dig_t1; 190 int16_t dig_t2; 191 int16_t dig_t3; 192 uint16_t dig_p1; 193 int16_t dig_p2; 194 int16_t dig_p3; 195 int16_t dig_p4; 196 int16_t dig_p5; 197 int16_t dig_p6; 198 int16_t dig_p7; 199 int16_t dig_p8; 200 int16_t dig_p9; 201 uint8_t dig_h1; 202 int16_t dig_h2; 203 uint8_t dig_h3; 204 int16_t dig_h4; 205 int16_t dig_h5; 206 int8_t dig_h6; 207 208 /* Carryover between temperature and pressure/humidity compensation. */ 209 int32_t t_fine; 210 211 uint8_t chip_id; 212 213 struct bme280_reading reading; 214 }; 215 216 /* 217 * RTIO 218 */ 219 220 struct bme280_decoder_header { 221 uint64_t timestamp; 222 } __attribute__((__packed__)); 223 224 struct bme280_encoded_data { 225 struct bme280_decoder_header header; 226 struct { 227 /** Set if `temp` has data */ 228 uint8_t has_temp: 1; 229 /** Set if `press` has data */ 230 uint8_t has_press: 1; 231 /** Set if `humidity` has data */ 232 uint8_t has_humidity: 1; 233 } __attribute__((__packed__)); 234 struct bme280_reading reading; 235 }; 236 237 int bme280_get_decoder(const struct device *dev, const struct sensor_decoder_api **decoder); 238 239 void bme280_submit(const struct device *dev, struct rtio_iodev_sqe *iodev_sqe); 240 241 int bme280_sample_fetch(const struct device *dev, enum sensor_channel chan); 242 243 int bme280_sample_fetch_helper(const struct device *dev, enum sensor_channel chan, 244 struct bme280_reading *reading); 245 246 #endif /* ZEPHYR_DRIVERS_SENSOR_BME280_BME280_H_ */ 247