summaryrefslogtreecommitdiff
path: root/nrfdemo/src/bme680/bme680.h
blob: 125aea1b27666a0b1a93447d12334ad58ad4f803 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
/*
 * Copyright (c) 2018 Bosch Sensortec GmbH
 * Copyright (c) 2022, Leonard Pollak
 *
 * SPDX-License-Identifier: Apache-2.0
 */

#ifndef __ZEPHYR_DRIVERS_SENSOR_BME680_H__
#define __ZEPHYR_DRIVERS_SENSOR_BME680_H__

#include <zephyr/types.h>
#include <zephyr/device.h>
#include <zephyr/devicetree.h>
#include <zephyr/drivers/spi.h>
#include <zephyr/drivers/i2c.h>

#define DT_DRV_COMPAT bosch_bme680

#define BME680_BUS_SPI DT_ANY_INST_ON_BUS_STATUS_OKAY(spi)
#define BME680_BUS_I2C DT_ANY_INST_ON_BUS_STATUS_OKAY(i2c)

union bme680_bus {
#if BME680_BUS_SPI
	struct spi_dt_spec spi;
#endif
#if BME680_BUS_I2C
	struct i2c_dt_spec i2c;
#endif
};

typedef int (*bme680_bus_check_fn)(const union bme680_bus *bus);
typedef int (*bme680_reg_read_fn)(const struct device *dev,
				  uint8_t start, uint8_t *buf, int size);
typedef int (*bme680_reg_write_fn)(const struct device *dev,
				   uint8_t reg, uint8_t val);

struct bme680_bus_io {
	bme680_bus_check_fn check;
	bme680_reg_read_fn read;
	bme680_reg_write_fn write;
};

#if BME680_BUS_SPI
#define BME680_SPI_OPERATION (SPI_WORD_SET(8) | SPI_TRANSFER_MSB | SPI_MODE_CPOL \
		| SPI_MODE_CPHA | SPI_OP_MODE_MASTER)
extern const struct bme680_bus_io bme680_bus_io_spi;
#endif

#if BME680_BUS_I2C
extern const struct bme680_bus_io bme680_bus_io_i2c;
#endif

struct bme680_config {
	union bme680_bus bus;
	const struct bme680_bus_io *bus_io;
};

#define BME680_CHIP_ID                  0x61

#define BME680_LEN_FIELD                15
#define BME680_LEN_COEFF_ALL            42
#define BME680_LEN_COEFF1               23
#define BME680_LEN_COEFF2               14
#define BME680_LEN_COEFF3               5

#define BME680_REG_COEFF3               0x00
#define BME680_REG_FIELD0               0x1d
#define BME680_REG_IDAC_HEAT0           0x50
#define BME680_REG_RES_HEAT0            0x5A
#define BME680_REG_GAS_WAIT0            0x64
#define BME680_REG_SHD_HEATR_DUR        0x6E
#define BME680_REG_CTRL_GAS_0           0x70
#define BME680_REG_CTRL_GAS_1           0x71
#define BME680_REG_CTRL_HUM             0x72
#define BME680_REG_CTRL_MEAS            0x74
#define BME680_REG_CONFIG               0x75
#define BME680_REG_STATUS               0x73
#define BME680_REG_UNIQUE_ID            0x83
#define BME680_REG_COEFF1               0x8a
#define BME680_REG_COEFF2               0xe1
#define BME680_REG_CHIP_ID		0xd0
#define BME680_REG_SOFT_RESET           0xe0

#define BME680_MSK_NEW_DATA             0x80
#define BME680_MSK_GAS_RANGE            0x0f
#define BME680_MSK_RH_RANGE             0x30
#define BME680_MSK_RANGE_SW_ERR         0xf0
#define BME680_MSK_HEATR_STAB           0x10

#define BME680_SPI_MEM_PAGE_MSK         0x10
#define BME680_SPI_MEM_PAGE_POS         4
#define BME680_SPI_READ_BIT             0x80
#define BME680_SPI_WRITE_MSK            0x7f

#if defined CONFIG_BME680_TEMP_OVER_1X
#define BME680_TEMP_OVER                (1 << 5)
#elif defined CONFIG_BME680_TEMP_OVER_2X
#define BME680_TEMP_OVER                (2 << 5)
#elif defined CONFIG_BME680_TEMP_OVER_4X
#define BME680_TEMP_OVER                (3 << 5)
#elif defined CONFIG_BME680_TEMP_OVER_8X
#define BME680_TEMP_OVER                (4 << 5)
#elif defined CONFIG_BME680_TEMP_OVER_16X
#define BME680_TEMP_OVER                (5 << 5)
#endif

#if defined CONFIG_BME680_PRESS_OVER_1X
#define BME680_PRESS_OVER               (1 << 2)
#elif defined CONFIG_BME680_PRESS_OVER_2X
#define BME680_PRESS_OVER               (2 << 2)
#elif defined CONFIG_BME680_PRESS_OVER_4X
#define BME680_PRESS_OVER               (3 << 2)
#elif defined CONFIG_BME680_PRESS_OVER_8X
#define BME680_PRESS_OVER               (4 << 2)
#elif defined CONFIG_BME680_PRESS_OVER_16X
#define BME680_PRESS_OVER               (5 << 2)
#endif

#if defined CONFIG_BME680_HUMIDITY_OVER_1X
#define BME680_HUMIDITY_OVER            1
#elif defined CONFIG_BME680_HUMIDITY_OVER_2X
#define BME680_HUMIDITY_OVER            2
#elif defined CONFIG_BME680_HUMIDITY_OVER_4X
#define BME680_HUMIDITY_OVER            3
#elif defined CONFIG_BME680_HUMIDITY_OVER_8X
#define BME680_HUMIDITY_OVER            4
#elif defined CONFIG_BME680_HUMIDITY_OVER_16X
#define BME680_HUMIDITY_OVER            5
#endif

#if defined CONFIG_BME680_HEATR_TEMP_LP
#define BME680_HEATR_TEMP                               320
#elif defined CONFIG_BME680_HEATR_TEMP_ULP
#define BME680_HEATR_TEMP                               400
#endif

#if defined CONFIG_BME680_HEATR_DUR_LP
#define BME680_HEATR_DUR_MS                             197
#elif defined CONFIG_BME680_HEATR_DUR_ULP
#define BME680_HEATR_DUR_MS                             1943
#endif

#if defined CONFIG_BME680_FILTER_OFF
#define BME680_FILTER                   0
#elif defined CONFIG_BME680_FILTER_2
#define BME680_FILTER                   (1 << 2)
#elif defined CONFIG_BME680_FILTER_4
#define BME680_FILTER                   (2 << 2)
#elif defined CONFIG_BME680_FILTER_8
#define BME680_FILTER                   (3 << 2)
#elif defined CONFIG_BME680_FILTER_16
#define BME680_FILTER                   (4 << 2)
#elif defined CONFIG_BME680_FILTER_32
#define BME680_FILTER                   (5 << 2)
#elif defined CONFIG_BME680_FILTER_64
#define BME680_FILTER                   (6 << 2)
#elif defined CONFIG_BME680_FILTER_128
#define BME680_FILTER                   (7 << 2)
#endif

#define BME680_MODE_SLEEP               0
#define BME680_MODE_FORCED              1

#define BME680_CTRL_MEAS_VAL    (BME680_PRESS_OVER | BME680_TEMP_OVER \
				 | BME680_MODE_FORCED)
#define BME680_CONFIG_VAL               BME680_FILTER
#define BME680_CTRL_GAS_1_VAL   0x10

#define BME680_CONCAT_BYTES(msb, lsb) (((uint16_t)msb << 8) | (uint16_t)lsb)

struct bme680_data {
	/* Compensation parameters. */
	uint16_t par_h1;
	uint16_t par_h2;
	int8_t par_h3;
	int8_t par_h4;
	int8_t par_h5;
	uint8_t par_h6;
	int8_t par_h7;
	int8_t par_gh1;
	int16_t par_gh2;
	int8_t par_gh3;
	uint16_t par_t1;
	int16_t par_t2;
	int8_t par_t3;
	uint16_t par_p1;
	int16_t par_p2;
	int8_t par_p3;
	int16_t par_p4;
	int16_t par_p5;
	int8_t par_p6;
	int8_t par_p7;
	int16_t par_p8;
	int16_t par_p9;
	uint8_t par_p10;
	uint8_t res_heat_range;
	int8_t res_heat_val;
	int8_t range_sw_err;

	/* Calculated sensor values. */
	int32_t calc_temp;
	uint32_t calc_press;
	uint32_t calc_humidity;
	uint32_t calc_gas_resistance;

	/* Additional information */
	uint8_t new_data;
	uint8_t heatr_stab;

	/* Carryover between temperature and pressure/humidity compensation. */
	int32_t t_fine;

	uint8_t chip_id;

#if BME680_BUS_SPI
	uint8_t mem_page;
#endif
};

#endif /* __ZEPHYR_DRIVERS_SENSOR_BME680_H__ */