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