1 /*
2  * Copyright (c) 2018 Bosch Sensortec GmbH
3  * Copyright (c) 2022, Leonard Pollak
4  *
5  * SPDX-License-Identifier: Apache-2.0
6  */
7 
8 #ifndef __ZEPHYR_DRIVERS_SENSOR_BME680_H__
9 #define __ZEPHYR_DRIVERS_SENSOR_BME680_H__
10 
11 #include <zephyr/types.h>
12 #include <zephyr/device.h>
13 #include <zephyr/devicetree.h>
14 #include <zephyr/drivers/spi.h>
15 #include <zephyr/drivers/i2c.h>
16 
17 #define DT_DRV_COMPAT bosch_bme680
18 
19 #define BME680_BUS_SPI DT_ANY_INST_ON_BUS_STATUS_OKAY(spi)
20 #define BME680_BUS_I2C DT_ANY_INST_ON_BUS_STATUS_OKAY(i2c)
21 
22 union bme680_bus {
23 #if BME680_BUS_SPI
24 	struct spi_dt_spec spi;
25 #endif
26 #if BME680_BUS_I2C
27 	struct i2c_dt_spec i2c;
28 #endif
29 };
30 
31 typedef int (*bme680_bus_check_fn)(const union bme680_bus *bus);
32 typedef int (*bme680_reg_read_fn)(const struct device *dev,
33 				  uint8_t start, uint8_t *buf, int size);
34 typedef int (*bme680_reg_write_fn)(const struct device *dev,
35 				   uint8_t reg, uint8_t val);
36 
37 struct bme680_bus_io {
38 	bme680_bus_check_fn check;
39 	bme680_reg_read_fn read;
40 	bme680_reg_write_fn write;
41 };
42 
43 #if BME680_BUS_SPI
44 #define BME680_SPI_OPERATION (SPI_WORD_SET(8) | SPI_TRANSFER_MSB | SPI_MODE_CPOL \
45 		| SPI_MODE_CPHA | SPI_OP_MODE_MASTER)
46 extern const struct bme680_bus_io bme680_bus_io_spi;
47 #endif
48 
49 #if BME680_BUS_I2C
50 extern const struct bme680_bus_io bme680_bus_io_i2c;
51 #endif
52 
53 struct bme680_config {
54 	union bme680_bus bus;
55 	const struct bme680_bus_io *bus_io;
56 };
57 
58 #define BME680_CHIP_ID                  0x61
59 
60 #define BME680_LEN_COEFF_ALL            42
61 #define BME680_LEN_COEFF1               23
62 #define BME680_LEN_COEFF2               14
63 #define BME680_LEN_COEFF3               5
64 
65 #define BME680_REG_COEFF3               0x00
66 #define BME680_REG_MEAS_STATUS          0x1D
67 #define BME680_REG_FIELD0               0x1F
68 #define BME680_REG_IDAC_HEAT0           0x50
69 #define BME680_REG_RES_HEAT0            0x5A
70 #define BME680_REG_GAS_WAIT0            0x64
71 #define BME680_REG_SHD_HEATR_DUR        0x6E
72 #define BME680_REG_CTRL_GAS_0           0x70
73 #define BME680_REG_CTRL_GAS_1           0x71
74 #define BME680_REG_CTRL_HUM             0x72
75 #define BME680_REG_STATUS               0x73
76 #define BME680_REG_CTRL_MEAS            0x74
77 #define BME680_REG_CONFIG               0x75
78 #define BME680_REG_UNIQUE_ID            0x83
79 #define BME680_REG_COEFF1               0x8a
80 #define BME680_REG_COEFF2               0xe1
81 #define BME680_REG_CHIP_ID		0xd0
82 #define BME680_REG_SOFT_RESET           0xe0
83 
84 #define BME680_MSK_NEW_DATA             0x80
85 #define BME680_MSK_GAS_RANGE            0x0f
86 #define BME680_MSK_RH_RANGE             0x30
87 #define BME680_MSK_RANGE_SW_ERR         0xf0
88 #define BME680_MSK_HEATR_STAB           0x10
89 
90 #define BME680_SPI_MEM_PAGE_MSK         0x10
91 #define BME680_SPI_MEM_PAGE_POS         4
92 #define BME680_SPI_READ_BIT             0x80
93 #define BME680_SPI_WRITE_MSK            0x7f
94 
95 #if defined CONFIG_BME680_TEMP_OVER_1X
96 #define BME680_TEMP_OVER                (1 << 5)
97 #elif defined CONFIG_BME680_TEMP_OVER_2X
98 #define BME680_TEMP_OVER                (2 << 5)
99 #elif defined CONFIG_BME680_TEMP_OVER_4X
100 #define BME680_TEMP_OVER                (3 << 5)
101 #elif defined CONFIG_BME680_TEMP_OVER_8X
102 #define BME680_TEMP_OVER                (4 << 5)
103 #elif defined CONFIG_BME680_TEMP_OVER_16X
104 #define BME680_TEMP_OVER                (5 << 5)
105 #endif
106 
107 #if defined CONFIG_BME680_PRESS_OVER_1X
108 #define BME680_PRESS_OVER               (1 << 2)
109 #elif defined CONFIG_BME680_PRESS_OVER_2X
110 #define BME680_PRESS_OVER               (2 << 2)
111 #elif defined CONFIG_BME680_PRESS_OVER_4X
112 #define BME680_PRESS_OVER               (3 << 2)
113 #elif defined CONFIG_BME680_PRESS_OVER_8X
114 #define BME680_PRESS_OVER               (4 << 2)
115 #elif defined CONFIG_BME680_PRESS_OVER_16X
116 #define BME680_PRESS_OVER               (5 << 2)
117 #endif
118 
119 #if defined CONFIG_BME680_HUMIDITY_OVER_1X
120 #define BME680_HUMIDITY_OVER            1
121 #elif defined CONFIG_BME680_HUMIDITY_OVER_2X
122 #define BME680_HUMIDITY_OVER            2
123 #elif defined CONFIG_BME680_HUMIDITY_OVER_4X
124 #define BME680_HUMIDITY_OVER            3
125 #elif defined CONFIG_BME680_HUMIDITY_OVER_8X
126 #define BME680_HUMIDITY_OVER            4
127 #elif defined CONFIG_BME680_HUMIDITY_OVER_16X
128 #define BME680_HUMIDITY_OVER            5
129 #endif
130 
131 #if defined CONFIG_BME680_HEATR_TEMP_LP
132 #define BME680_HEATR_TEMP                               320
133 #elif defined CONFIG_BME680_HEATR_TEMP_ULP
134 #define BME680_HEATR_TEMP                               400
135 #endif
136 
137 #if defined CONFIG_BME680_HEATR_DUR_LP
138 #define BME680_HEATR_DUR_MS                             197
139 #elif defined CONFIG_BME680_HEATR_DUR_ULP
140 #define BME680_HEATR_DUR_MS                             1943
141 #endif
142 
143 #if defined CONFIG_BME680_FILTER_OFF
144 #define BME680_FILTER                   0
145 #elif defined CONFIG_BME680_FILTER_2
146 #define BME680_FILTER                   (1 << 2)
147 #elif defined CONFIG_BME680_FILTER_4
148 #define BME680_FILTER                   (2 << 2)
149 #elif defined CONFIG_BME680_FILTER_8
150 #define BME680_FILTER                   (3 << 2)
151 #elif defined CONFIG_BME680_FILTER_16
152 #define BME680_FILTER                   (4 << 2)
153 #elif defined CONFIG_BME680_FILTER_32
154 #define BME680_FILTER                   (5 << 2)
155 #elif defined CONFIG_BME680_FILTER_64
156 #define BME680_FILTER                   (6 << 2)
157 #elif defined CONFIG_BME680_FILTER_128
158 #define BME680_FILTER                   (7 << 2)
159 #endif
160 
161 #define BME680_MODE_SLEEP               0
162 #define BME680_MODE_FORCED              1
163 
164 #define BME680_CTRL_MEAS_VAL    (BME680_PRESS_OVER | BME680_TEMP_OVER \
165 				 | BME680_MODE_FORCED)
166 #define BME680_CONFIG_VAL               BME680_FILTER
167 #define BME680_CTRL_GAS_1_VAL   0x10
168 
169 #define BME680_CONCAT_BYTES(msb, lsb) (((uint16_t)msb << 8) | (uint16_t)lsb)
170 
171 struct bme680_data {
172 	/* Compensation parameters. */
173 	uint16_t par_h1;
174 	uint16_t par_h2;
175 	int8_t par_h3;
176 	int8_t par_h4;
177 	int8_t par_h5;
178 	uint8_t par_h6;
179 	int8_t par_h7;
180 	int8_t par_gh1;
181 	int16_t par_gh2;
182 	int8_t par_gh3;
183 	uint16_t par_t1;
184 	int16_t par_t2;
185 	int8_t par_t3;
186 	uint16_t par_p1;
187 	int16_t par_p2;
188 	int8_t par_p3;
189 	int16_t par_p4;
190 	int16_t par_p5;
191 	int8_t par_p6;
192 	int8_t par_p7;
193 	int16_t par_p8;
194 	int16_t par_p9;
195 	uint8_t par_p10;
196 	uint8_t res_heat_range;
197 	int8_t res_heat_val;
198 	int8_t range_sw_err;
199 
200 	/* Calculated sensor values. */
201 	int32_t calc_temp;
202 	uint32_t calc_press;
203 	uint32_t calc_humidity;
204 	uint32_t calc_gas_resistance;
205 
206 	/* Additional information */
207 	uint8_t heatr_stab;
208 
209 	/* Carryover between temperature and pressure/humidity compensation. */
210 	int32_t t_fine;
211 
212 	uint8_t chip_id;
213 
214 #if BME680_BUS_SPI
215 	uint8_t mem_page;
216 #endif
217 };
218 
219 #endif /* __ZEPHYR_DRIVERS_SENSOR_BME680_H__ */
220