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