1 /* bme280.c - Driver for Bosch BME280 temperature and pressure sensor */
2 
3 /*
4  * Copyright (c) 2016, 2017 Intel Corporation
5  * Copyright (c) 2017 IpTronix S.r.l.
6  * Copyright (c) 2021 Nordic Semiconductor ASA
7  *
8  * SPDX-License-Identifier: Apache-2.0
9  */
10 
11 #include <zephyr/kernel.h>
12 #include <zephyr/drivers/sensor.h>
13 #include <zephyr/init.h>
14 #include <zephyr/drivers/gpio.h>
15 #include <zephyr/pm/device.h>
16 #include <zephyr/sys/byteorder.h>
17 #include <zephyr/sys/__assert.h>
18 
19 #include <zephyr/logging/log.h>
20 
21 #include "bme280.h"
22 
23 LOG_MODULE_REGISTER(BME280, CONFIG_SENSOR_LOG_LEVEL);
24 
25 #if DT_NUM_INST_STATUS_OKAY(DT_DRV_COMPAT) == 0
26 #warning "BME280 driver enabled without any devices"
27 #endif
28 
29 /* Maximum oversampling rate on each channel is 16x.
30  * Maximum measurement time is given by (Datasheet appendix B 9.1):
31  *    1.25 + [2.3 * T_over] + [2.3 * P_over + 0.575] + [2.3 * H_over + 0.575]
32  *    = 112.8 ms
33  */
34 #define BME280_MEASUREMENT_TIMEOUT_MS 150
35 
36 /* Start-up time - Time to first communication after both Vdd > 1.58V and
37  * Vddio > 0.65V
38  */
39 #define BME280_START_UP_TIME_MS 2
40 
41 /* Equation 9.1, with the fractional parts rounded down */
42 #define BME280_EXPECTED_SAMPLE_TIME_MS                                                             \
43 	1 + BME280_TEMP_SAMPLE_TIME + BME280_PRESS_SAMPLE_TIME + BME280_HUMIDITY_SAMPLE_TIME
44 
45 BUILD_ASSERT(BME280_EXPECTED_SAMPLE_TIME_MS < BME280_MEASUREMENT_TIMEOUT_MS,
46 	     "Expected duration over timeout duration");
47 
48 struct bme280_config {
49 	union bme280_bus bus;
50 	const struct bme280_bus_io *bus_io;
51 };
52 
bme280_bus_check(const struct device * dev)53 static inline int bme280_bus_check(const struct device *dev)
54 {
55 	const struct bme280_config *cfg = dev->config;
56 
57 	return cfg->bus_io->check(&cfg->bus);
58 }
59 
bme280_reg_read(const struct device * dev,uint8_t start,uint8_t * buf,int size)60 static inline int bme280_reg_read(const struct device *dev,
61 				  uint8_t start, uint8_t *buf, int size)
62 {
63 	const struct bme280_config *cfg = dev->config;
64 
65 	return cfg->bus_io->read(&cfg->bus, start, buf, size);
66 }
67 
bme280_reg_write(const struct device * dev,uint8_t reg,uint8_t val)68 static inline int bme280_reg_write(const struct device *dev, uint8_t reg,
69 				   uint8_t val)
70 {
71 	const struct bme280_config *cfg = dev->config;
72 
73 	return cfg->bus_io->write(&cfg->bus, reg, val);
74 }
75 
76 /*
77  * Compensation code taken from BME280 datasheet, Section 4.2.3
78  * "Compensation formula".
79  */
bme280_compensate_temp(struct bme280_data * data,int32_t adc_temp)80 static int32_t bme280_compensate_temp(struct bme280_data *data, int32_t adc_temp)
81 {
82 	int32_t var1, var2;
83 
84 	var1 = (((adc_temp >> 3) - ((int32_t)data->dig_t1 << 1)) *
85 		((int32_t)data->dig_t2)) >> 11;
86 	var2 = (((((adc_temp >> 4) - ((int32_t)data->dig_t1)) *
87 		  ((adc_temp >> 4) - ((int32_t)data->dig_t1))) >> 12) *
88 		((int32_t)data->dig_t3)) >> 14;
89 
90 	data->t_fine = var1 + var2;
91 	return (data->t_fine * 5 + 128) >> 8;
92 }
93 
bme280_compensate_press(struct bme280_data * data,int32_t adc_press)94 static uint32_t bme280_compensate_press(struct bme280_data *data, int32_t adc_press)
95 {
96 	int64_t var1, var2, p;
97 
98 	var1 = ((int64_t)data->t_fine) - 128000;
99 	var2 = var1 * var1 * (int64_t)data->dig_p6;
100 	var2 = var2 + ((var1 * (int64_t)data->dig_p5) << 17);
101 	var2 = var2 + (((int64_t)data->dig_p4) << 35);
102 	var1 = ((var1 * var1 * (int64_t)data->dig_p3) >> 8) +
103 		((var1 * (int64_t)data->dig_p2) << 12);
104 	var1 = (((((int64_t)1) << 47) + var1)) * ((int64_t)data->dig_p1) >> 33;
105 
106 	/* Avoid exception caused by division by zero. */
107 	if (var1 == 0) {
108 		return 0;
109 	}
110 
111 	p = 1048576 - adc_press;
112 	p = (((p << 31) - var2) * 3125) / var1;
113 	var1 = (((int64_t)data->dig_p9) * (p >> 13) * (p >> 13)) >> 25;
114 	var2 = (((int64_t)data->dig_p8) * p) >> 19;
115 	p = ((p + var1 + var2) >> 8) + (((int64_t)data->dig_p7) << 4);
116 
117 	return (uint32_t)p;
118 }
119 
bme280_compensate_humidity(struct bme280_data * data,int32_t adc_humidity)120 static uint32_t bme280_compensate_humidity(struct bme280_data *data,
121 				       int32_t adc_humidity)
122 {
123 	int32_t h;
124 
125 	h = (data->t_fine - ((int32_t)76800));
126 	h = ((((adc_humidity << 14) - (((int32_t)data->dig_h4) << 20) -
127 		(((int32_t)data->dig_h5) * h)) + ((int32_t)16384)) >> 15) *
128 		(((((((h * ((int32_t)data->dig_h6)) >> 10) * (((h *
129 		((int32_t)data->dig_h3)) >> 11) + ((int32_t)32768))) >> 10) +
130 		((int32_t)2097152)) * ((int32_t)data->dig_h2) + 8192) >> 14);
131 	h = (h - (((((h >> 15) * (h >> 15)) >> 7) *
132 		((int32_t)data->dig_h1)) >> 4));
133 	h = (h > 419430400 ? 419430400 : h);
134 	h = (h < 0 ? 0 : h);
135 
136 	return (uint32_t)(h >> 12);
137 }
138 
bme280_wait_until_ready(const struct device * dev,k_timeout_t timeout)139 static int bme280_wait_until_ready(const struct device *dev, k_timeout_t timeout)
140 {
141 	k_timepoint_t end = sys_timepoint_calc(timeout);
142 	uint8_t status;
143 	int ret;
144 
145 	/* Wait for relevant flags to clear */
146 	while (1) {
147 		ret = bme280_reg_read(dev, BME280_REG_STATUS, &status, 1);
148 		if (ret < 0) {
149 			return ret;
150 		}
151 		if (!(status & (BME280_STATUS_MEASURING | BME280_STATUS_IM_UPDATE))) {
152 			break;
153 		}
154 		/* Check if waiting has timed out */
155 		if (sys_timepoint_expired(end)) {
156 			return -EAGAIN;
157 		}
158 		k_sleep(K_MSEC(3));
159 	}
160 
161 	return 0;
162 }
163 
bme280_sample_fetch_helper(const struct device * dev,enum sensor_channel chan,struct bme280_reading * reading)164 int bme280_sample_fetch_helper(const struct device *dev,
165 			       enum sensor_channel chan, struct bme280_reading *reading)
166 {
167 	struct bme280_data *dev_data = dev->data;
168 	uint8_t buf[8];
169 	int32_t adc_press, adc_temp, adc_humidity;
170 	uint32_t poll_timeout;
171 	int size = 6;
172 	int ret;
173 
174 	__ASSERT_NO_MSG(chan == SENSOR_CHAN_ALL);
175 
176 #ifdef CONFIG_BME280_MODE_FORCED
177 	ret = bme280_reg_write(dev, BME280_REG_CTRL_MEAS, BME280_CTRL_MEAS_VAL);
178 	if (ret < 0) {
179 		return ret;
180 	}
181 	/* Wait until the expected measurement time elapses */
182 	k_sleep(K_MSEC(BME280_EXPECTED_SAMPLE_TIME_MS));
183 	poll_timeout = BME280_MEASUREMENT_TIMEOUT_MS - BME280_EXPECTED_SAMPLE_TIME_MS;
184 #else
185 	poll_timeout = BME280_MEASUREMENT_TIMEOUT_MS;
186 #endif
187 
188 	ret = bme280_wait_until_ready(dev, K_MSEC(poll_timeout));
189 	if (ret < 0) {
190 		return ret;
191 	}
192 
193 	if (dev_data->chip_id == BME280_CHIP_ID) {
194 		size = 8;
195 	}
196 	ret = bme280_reg_read(dev, BME280_REG_PRESS_MSB, buf, size);
197 	if (ret < 0) {
198 		return ret;
199 	}
200 
201 	adc_press = (buf[0] << 12) | (buf[1] << 4) | (buf[2] >> 4);
202 	adc_temp = (buf[3] << 12) | (buf[4] << 4) | (buf[5] >> 4);
203 
204 	reading->comp_temp = bme280_compensate_temp(dev_data, adc_temp);
205 	reading->comp_press = bme280_compensate_press(dev_data, adc_press);
206 
207 	if (dev_data->chip_id == BME280_CHIP_ID) {
208 		adc_humidity = (buf[6] << 8) | buf[7];
209 		reading->comp_humidity = bme280_compensate_humidity(dev_data, adc_humidity);
210 	}
211 
212 	return 0;
213 }
214 
bme280_sample_fetch(const struct device * dev,enum sensor_channel chan)215 int bme280_sample_fetch(const struct device *dev, enum sensor_channel chan)
216 {
217 	struct bme280_data *data = dev->data;
218 
219 	return bme280_sample_fetch_helper(dev, chan, &data->reading);
220 }
221 
bme280_channel_get(const struct device * dev,enum sensor_channel chan,struct sensor_value * val)222 static int bme280_channel_get(const struct device *dev,
223 			      enum sensor_channel chan,
224 			      struct sensor_value *val)
225 {
226 	struct bme280_data *data = dev->data;
227 
228 	switch (chan) {
229 	case SENSOR_CHAN_AMBIENT_TEMP:
230 		/*
231 		 * comp_temp has a resolution of 0.01 degC.  So
232 		 * 5123 equals 51.23 degC.
233 		 */
234 		val->val1 = data->reading.comp_temp / 100;
235 		val->val2 = data->reading.comp_temp % 100 * 10000;
236 		break;
237 	case SENSOR_CHAN_PRESS:
238 		/*
239 		 * comp_press has 24 integer bits and 8
240 		 * fractional.  Output value of 24674867 represents
241 		 * 24674867/256 = 96386.2 Pa = 963.862 hPa
242 		 */
243 		val->val1 = (data->reading.comp_press >> 8) / 1000U;
244 		val->val2 = (data->reading.comp_press >> 8) % 1000 * 1000U +
245 			(((data->reading.comp_press & 0xff) * 1000U) >> 8);
246 		break;
247 	case SENSOR_CHAN_HUMIDITY:
248 		/* The BMP280 doesn't have a humidity sensor */
249 		if (data->chip_id != BME280_CHIP_ID) {
250 			return -ENOTSUP;
251 		}
252 		/*
253 		 * comp_humidity has 22 integer bits and 10
254 		 * fractional.  Output value of 47445 represents
255 		 * 47445/1024 = 46.333 %RH
256 		 */
257 		val->val1 = (data->reading.comp_humidity >> 10);
258 		val->val2 = (((data->reading.comp_humidity & 0x3ff) * 1000U * 1000U) >> 10);
259 		break;
260 	default:
261 		return -ENOTSUP;
262 	}
263 
264 	return 0;
265 }
266 
267 static DEVICE_API(sensor, bme280_api_funcs) = {
268 	.sample_fetch = bme280_sample_fetch,
269 	.channel_get = bme280_channel_get,
270 #ifdef CONFIG_SENSOR_ASYNC_API
271 	.submit = bme280_submit,
272 	.get_decoder = bme280_get_decoder,
273 #endif
274 };
275 
bme280_read_compensation(const struct device * dev)276 static int bme280_read_compensation(const struct device *dev)
277 {
278 	struct bme280_data *data = dev->data;
279 	uint16_t buf[12];
280 	uint8_t hbuf[7];
281 	int err = 0;
282 
283 	err = bme280_reg_read(dev, BME280_REG_COMP_START,
284 			      (uint8_t *)buf, sizeof(buf));
285 
286 	if (err < 0) {
287 		LOG_DBG("COMP_START read failed: %d", err);
288 		return err;
289 	}
290 
291 	data->dig_t1 = sys_le16_to_cpu(buf[0]);
292 	data->dig_t2 = sys_le16_to_cpu(buf[1]);
293 	data->dig_t3 = sys_le16_to_cpu(buf[2]);
294 
295 	data->dig_p1 = sys_le16_to_cpu(buf[3]);
296 	data->dig_p2 = sys_le16_to_cpu(buf[4]);
297 	data->dig_p3 = sys_le16_to_cpu(buf[5]);
298 	data->dig_p4 = sys_le16_to_cpu(buf[6]);
299 	data->dig_p5 = sys_le16_to_cpu(buf[7]);
300 	data->dig_p6 = sys_le16_to_cpu(buf[8]);
301 	data->dig_p7 = sys_le16_to_cpu(buf[9]);
302 	data->dig_p8 = sys_le16_to_cpu(buf[10]);
303 	data->dig_p9 = sys_le16_to_cpu(buf[11]);
304 
305 	if (data->chip_id == BME280_CHIP_ID) {
306 		err = bme280_reg_read(dev, BME280_REG_HUM_COMP_PART1,
307 				      &data->dig_h1, 1);
308 		if (err < 0) {
309 			LOG_DBG("HUM_COMP_PART1 read failed: %d", err);
310 			return err;
311 		}
312 
313 		err = bme280_reg_read(dev, BME280_REG_HUM_COMP_PART2, hbuf, 7);
314 		if (err < 0) {
315 			LOG_DBG("HUM_COMP_PART2 read failed: %d", err);
316 			return err;
317 		}
318 
319 		data->dig_h2 = (hbuf[1] << 8) | hbuf[0];
320 		data->dig_h3 = hbuf[2];
321 		data->dig_h4 = (hbuf[3] << 4) | (hbuf[4] & 0x0F);
322 		data->dig_h5 = ((hbuf[4] >> 4) & 0x0F) | (hbuf[5] << 4);
323 		data->dig_h6 = hbuf[6];
324 	}
325 
326 	return 0;
327 }
328 
bme280_chip_init(const struct device * dev)329 static int bme280_chip_init(const struct device *dev)
330 {
331 	struct bme280_data *data = dev->data;
332 	int err;
333 
334 	err = bme280_bus_check(dev);
335 	if (err < 0) {
336 		LOG_DBG("bus check failed: %d", err);
337 		return err;
338 	}
339 
340 	k_msleep(BME280_START_UP_TIME_MS);
341 
342 	err = bme280_reg_read(dev, BME280_REG_ID, &data->chip_id, 1);
343 	if (err < 0) {
344 		LOG_DBG("ID read failed: %d", err);
345 		return err;
346 	}
347 
348 	if (data->chip_id == BME280_CHIP_ID) {
349 		LOG_DBG("ID OK");
350 	} else if (data->chip_id == BMP280_CHIP_ID_MP ||
351 		   data->chip_id == BMP280_CHIP_ID_SAMPLE_1) {
352 		LOG_DBG("ID OK (BMP280)");
353 	} else {
354 		LOG_DBG("bad chip id 0x%x", data->chip_id);
355 		return -ENOTSUP;
356 	}
357 
358 	/* reset the sensor. This will put the sensor is sleep mode */
359 	err = bme280_reg_write(dev, BME280_REG_RESET, BME280_CMD_SOFT_RESET);
360 	if (err < 0) {
361 		LOG_DBG("Soft-reset failed: %d", err);
362 	}
363 
364 	/* The only mention of a soft reset duration is 2ms from the self test timeouts */
365 	err = bme280_wait_until_ready(dev, K_MSEC(100));
366 	if (err < 0) {
367 		return err;
368 	}
369 
370 	err = bme280_read_compensation(dev);
371 	if (err < 0) {
372 		return err;
373 	}
374 
375 	if (data->chip_id == BME280_CHIP_ID) {
376 		err = bme280_reg_write(dev, BME280_REG_CTRL_HUM,
377 				       BME280_HUMIDITY_OVER);
378 		if (err < 0) {
379 			LOG_DBG("CTRL_HUM write failed: %d", err);
380 			return err;
381 		}
382 	}
383 
384 	/* Writes to "config" register may be ignored in normal
385 	 * mode, but never in sleep mode [datasheet 5.4.6].
386 	 *
387 	 * So perform "config" write before "ctrl_meas", as "ctrl_meas"
388 	 * could cause the sensor to transition from sleep to normal mode.
389 	 */
390 	err = bme280_reg_write(dev, BME280_REG_CONFIG, BME280_CONFIG_VAL);
391 	if (err < 0) {
392 		LOG_DBG("CONFIG write failed: %d", err);
393 		return err;
394 	}
395 
396 	err = bme280_reg_write(dev, BME280_REG_CTRL_MEAS, BME280_CTRL_MEAS_VAL);
397 	if (err < 0) {
398 		LOG_DBG("CTRL_MEAS write failed: %d", err);
399 		return err;
400 	}
401 	/* Wait for the sensor to be ready */
402 	k_sleep(K_MSEC(1));
403 
404 	LOG_DBG("\"%s\" OK", dev->name);
405 	return 0;
406 }
407 
408 #ifdef CONFIG_PM_DEVICE
bme280_pm_action(const struct device * dev,enum pm_device_action action)409 static int bme280_pm_action(const struct device *dev,
410 			    enum pm_device_action action)
411 {
412 	int ret = 0;
413 
414 	switch (action) {
415 #ifdef CONFIG_BME280_MODE_NORMAL
416 	case PM_DEVICE_ACTION_RESUME:
417 		/* Re-enable periodic measurement */
418 		ret = bme280_reg_write(dev, BME280_REG_CTRL_MEAS, BME280_CTRL_MEAS_VAL);
419 		break;
420 	case PM_DEVICE_ACTION_SUSPEND:
421 		/* Put the chip into sleep mode */
422 		ret = bme280_reg_write(dev, BME280_REG_CTRL_MEAS, BME280_CTRL_MEAS_OFF_VAL);
423 		break;
424 #else
425 	case PM_DEVICE_ACTION_RESUME:
426 	case PM_DEVICE_ACTION_SUSPEND:
427 		/* Nothing to do in forced mode */
428 		break;
429 #endif
430 	default:
431 		return -ENOTSUP;
432 	}
433 
434 	return ret;
435 }
436 #endif /* CONFIG_PM_DEVICE */
437 
438 /* Initializes a struct bme280_config for an instance on a SPI bus. */
439 #define BME280_CONFIG_SPI(inst)				\
440 	{						\
441 		.bus.spi = SPI_DT_SPEC_INST_GET(	\
442 			inst, BME280_SPI_OPERATION),	\
443 		.bus_io = &bme280_bus_io_spi,		\
444 	}
445 
446 /* Initializes a struct bme280_config for an instance on an I2C bus. */
447 #define BME280_CONFIG_I2C(inst)			       \
448 	{					       \
449 		.bus.i2c = I2C_DT_SPEC_INST_GET(inst), \
450 		.bus_io = &bme280_bus_io_i2c,	       \
451 	}
452 
453 /*
454  * Main instantiation macro, which selects the correct bus-specific
455  * instantiation macros for the instance.
456  */
457 #define BME280_DEFINE(inst)						\
458 	static struct bme280_data bme280_data_##inst;			\
459 	static const struct bme280_config bme280_config_##inst =	\
460 		COND_CODE_1(DT_INST_ON_BUS(inst, spi),			\
461 			    (BME280_CONFIG_SPI(inst)),			\
462 			    (BME280_CONFIG_I2C(inst)));			\
463 									\
464 	PM_DEVICE_DT_INST_DEFINE(inst, bme280_pm_action);		\
465 									\
466 	SENSOR_DEVICE_DT_INST_DEFINE(inst,				\
467 			 bme280_chip_init,				\
468 			 PM_DEVICE_DT_INST_GET(inst),			\
469 			 &bme280_data_##inst,				\
470 			 &bme280_config_##inst,				\
471 			 POST_KERNEL,					\
472 			 CONFIG_SENSOR_INIT_PRIORITY,			\
473 			 &bme280_api_funcs);
474 
475 /* Create the struct device for every status "okay" node in the devicetree. */
476 DT_INST_FOREACH_STATUS_OKAY(BME280_DEFINE)
477