1/**
2* Copyright (c) 2024 Bosch Sensortec GmbH. All rights reserved.
3*
4* gas_bmr688_driver.h as part of the * /chipsets subdirectory
5* is dual licensed: you can use it either under the terms of
6* the GPL, or the BSD license, at your option.
7* See the LICENSE file in the root of this repository for complete details.
8*/
9
10#ifndef BME688_H
11#define BME688_H
12
13#include "sensor_gas_driver.h"
14#include "sensor_config_parser.h"
15
16#define BME688_AMB_TEMP                (int8_t)25       /*ambient temperature*/
17#define BME688_HEATR_TEMP              300              /*heating temperature*/
18#define BME688_HEATR_DUR               100              /*heating duration*/
19
20#if !defined(BME_UINT32_C)
21#define BME_UINT32_C(val) val ## U
22#endif
23
24#if !defined(BME_INT32_C)
25#define BME_INT32_C(val) val ## L
26#endif
27
28#define BME68X_CHIP_ID                 0x61     /* BME68X unique chip identifier */
29
30#define BME68X_REG_CTRL_MEAS           0x74     /* CTRL_MEAS address */
31#define BME68X_REG_COEFF1              0x8a     /* Register for 1st group of coefficients */
32#define BME68X_REG_COEFF2              0xe1     /* Register for 2nd group of coefficients */
33#define BME68X_REG_COEFF3              0x00     /* Register for 3rd group of coefficients */
34#define BME68X_REG_CHIP_ID             0xd0     /* Chip ID address */
35#define BME68X_REG_SOFT_RESET          0xe0     /* Soft reset address */
36#define BME68X_REG_VARIANT_ID          0xF0     /* Variant ID Register */
37#define BME68X_REG_FIELD0              0x1d     /* 0th Field address*/
38#define BME68X_REG_RES_HEAT0           0x5a     /* 0th Res heat address */
39#define BME68X_REG_IDAC_HEAT0          0x50     /* 0th Current DAC address*/
40#define BME68X_REG_GAS_WAIT0           0x64     /* 0th Gas wait address */
41#define BME68X_REG_CTRL_GAS_0          0x70     /* CTRL_GAS_0 address */
42#define BME68X_REG_CTRL_GAS_1          0x71     /* CTRL_GAS_1 address */
43#define BME68X_SOFT_RESET_CMD          0xb6     /* Soft reset command */
44
45#define BME68X_LEN_COEFF_ALL           42       /* Length for all coefficients */
46#define BME68X_LEN_COEFF1              23       /* Length for 1st group of coefficients */
47#define BME68X_LEN_COEFF2              14       /* Length for 2nd group of coefficients */
48#define BME68X_LEN_COEFF3              5        /* Length for 3rd group of coefficients */
49#define BME68X_LEN_CONFIG              5        /* Length of the configuration register */
50#define BME68X_LEN_FIELD               17       /* Length of the field */
51#define BME68X_LEN_FIELD_OFFSET        17       /* Length between two fields */
52
53#define BME68X_MODE_MSK                0x03     /* Mask for operation mode */
54
55#define BME68X_GASM_VALID_MSK          0x20     /* Mask for gas measurement valid */
56#define BME68X_GAS_INDEX_MSK           0x0f     /* Mask for gas index */
57#define BME68X_GAS_RANGE_MSK           0x0f     /* Mask for gas range */
58#define BME68X_GASM_VALID_MSK          0x20     /* Mask for gas measurement valid */
59#define BME68X_HEAT_STAB_MSK           0x10     /* Mask for heater stability */
60#define BME68X_NEW_DATA_MSK            0x80     /* Mask for new data */
61#define BME68X_BIT_H1_DATA_MSK         0x0f     /* Mask for the H1 calibration coefficient */
62#define BME68X_RHRANGE_MSK             0x30     /* Mask for res heat range */
63#define BME68X_RSERROR_MSK             0xf0     /* Mask for range switching error */
64
65#define BME68X_FILTER_MSK              0X1c     /* Mask for IIR filter */
66#define BME68X_OST_MSK                 0Xe0     /* Mask for temperature oversampling */
67#define BME68X_OSP_MSK                 0X1c     /* Mask for pressure oversampling */
68#define BME68X_OSH_MSK                 0X07     /* Mask for humidity oversampling */
69#define BME68X_ODR20_MSK               0xe0     /* Mask for ODR[2:0] */
70#define BME68X_ODR3_MSK                0x80     /* Mask for ODR[3] */
71#define BME68X_HCTRL_MSK               0x08     /* Mask for heater control */
72#define BME68X_NBCONV_MSK              0X0f     /* Mask for number of conversions */
73#define BME68X_RUN_GAS_MSK             0x30     /* Mask for run gas */
74#define BME688_NEW_DATA_READY          0x80     /* Mask for new data */
75
76#define BME68X_SLEEP_MODE              0        /* Sleep operation mode */
77#define BME68X_FORCED_MODE             1        /* Forced operation mode */
78#define BME68X_PARALLEL_MODE           2        /* Parallel operation mode */
79
80#define BME68X_VARIANT_GAS_HIGH        0x01     /* High Gas variant */
81
82#define BME68X_IDX_T1_LSB              31       /* Coefficient T1 LSB position */
83#define BME68X_IDX_T1_MSB              32       /* Coefficient T1 MSB position */
84#define BME68X_IDX_T2_LSB              0        /* Coefficient T2 LSB position */
85#define BME68X_IDX_T2_MSB              1        /* Coefficient T2 MSB position */
86#define BME68X_IDX_T3                  2        /* Coefficient T3 position */
87#define BME68X_IDX_P1_LSB              4        /* Coefficient P1 LSB position */
88#define BME68X_IDX_P1_MSB              5        /* Coefficient P1 MSB position */
89#define BME68X_IDX_P2_LSB              6        /* Coefficient P2 LSB position */
90#define BME68X_IDX_P2_MSB              7        /* Coefficient P2 MSB position */
91#define BME68X_IDX_P3                  8        /* Coefficient P3 position */
92#define BME68X_IDX_P4_LSB              10       /* Coefficient P4 LSB position */
93#define BME68X_IDX_P4_MSB              11       /* Coefficient P4 MSB position */
94#define BME68X_IDX_P5_LSB              12       /* Coefficient P5 LSB position */
95#define BME68X_IDX_P5_MSB              13       /* Coefficient P5 MSB position */
96#define BME68X_IDX_P7                  14       /* Coefficient P7 position */
97#define BME68X_IDX_P6                  15       /* Coefficient P6 position */
98#define BME68X_IDX_P8_LSB              18       /* Coefficient P8 LSB position */
99#define BME68X_IDX_P8_MSB              19       /* Coefficient P8 MSB position */
100#define BME68X_IDX_P9_LSB              20       /* Coefficient P9 LSB position */
101#define BME68X_IDX_P9_MSB              21       /* Coefficient P9 MSB position */
102#define BME68X_IDX_P10                 22       /* Coefficient P10 position */
103#define BME68X_IDX_H2_MSB              23       /* Coefficient H2 MSB position */
104#define BME68X_IDX_H2_LSB              24       /* Coefficient H2 LSB position */
105#define BME68X_IDX_H1_LSB              24       /* Coefficient H1 LSB position */
106#define BME68X_IDX_H1_MSB              25       /* Coefficient H1 MSB position */
107#define BME68X_IDX_H3                  26       /* Coefficient H3 position */
108#define BME68X_IDX_H4                  27       /* Coefficient H4 position */
109#define BME68X_IDX_H5                  28       /* Coefficient H5 position */
110#define BME68X_IDX_H6                  29       /* Coefficient H6 position */
111#define BME68X_IDX_H7                  30       /* Coefficient H7 position */
112#define BME68X_IDX_T1_LSB              31       /* Coefficient T1 LSB position */
113#define BME68X_IDX_T1_MSB              32       /* Coefficient T1 MSB position */
114#define BME68X_IDX_GH2_LSB             33       /* Coefficient GH2 LSB position */
115#define BME68X_IDX_GH2_MSB             34       /* Coefficient GH2 MSB position */
116#define BME68X_IDX_GH1                 35       /* Coefficient GH1 position */
117#define BME68X_IDX_GH3                 36       /* Coefficient GH3 position */
118#define BME68X_IDX_RES_HEAT_VAL        37       /* Coefficient res heat value position */
119#define BME68X_IDX_RES_HEAT_RANGE      39       /* Coefficient res heat range position */
120#define BME68X_IDX_RANGE_SW_ERR        41       /* Coefficient range switching error position */
121
122#define BME68X_FILTER_SIZE_127         7        /* Filter coefficient of 128 */
123
124#define BME68X_OS_1X                   1        /* Perform 1 measurement */
125#define BME68X_OS_2X                   2        /* Perform 2 measurements */
126#define BME68X_OS_4X                   3        /* Perform 4 measurements */
127#define BME68X_OS_8X                   4        /* Perform 8 measurements */
128#define BME68X_OS_16X                  5        /* Perform 16 measurements */
129#define BME68X_ODR_NONE                8        /* No standby time */
130
131#define BME68X_FILTER_OFF              0        /* Switch off the filter */
132
133#define BME68X_ENABLE                  0x01     /* Enable */
134#define BME68X_DISABLE                 0x00     /* Disable */
135#define BME68X_DISABLE_HEATER          0x01     /* Disable heater */
136#define BME68X_ENABLE_GAS_MEAS_L       0x01     /* Enable gas measurement low */
137#define BME68X_ENABLE_GAS_MEAS_H       0x02     /* Enable gas measurement high */
138#define BME68X_DISABLE_GAS_MEAS        0x00     /* Disable gas measurement */
139#define BME68X_ENABLE_HEATER           0x00     /* Enable heater */
140
141#define BME68X_HCTRL_POS               3        /* Heater control bit position */
142#define BME68X_RUN_GAS_POS             4        /* Run gas bit position */
143#define BME68X_FILTER_POS              2        /* Filter bit position */
144#define BME68X_OST_POS                 5        /* Temperature oversampling bit position */
145#define BME68X_OSP_POS                 2        /* Pressure oversampling bit position */
146#define BME68X_ODR3_POS                7        /* ODR[3] bit position */
147#define BME68X_ODR20_POS               5        /* ODR[2:0] bit position */
148
149#define BME688_WORK_MODE_SUSPEND       1        /* Suspend mode */
150#define BME688_WORK_MODE_IDLE          2        /* idle mode */
151
152#define BME688_DELAY_4                 4        /*delay time about 4 */
153#define BME688_DELAY_5                 5        /*delay time about 5 */
154#define BME688_DELAY_10                10       /*delay time about 10 */
155#define BME688_DELAY_50                50       /*delay time about 50 */
156
157#define BME688_MAX_HUM                 100000   /* max humidity  */
158#define BME688_MAX_TEMP                400      /* max temperature  */
159
160#define BME68X_LEN_INTERLEAVE_BUFF     20       /* Length of the interleaved buffer */
161
162#define BME688_TRY_TIMES               5        /* try to read field data times*/
163
164/* Macro to combine two 8 bit data's to form a 16 bit data */
165#define BME68X_CONCAT_BYTES(msb, lsb)          ((uint16_t)((msb) << 8) | (uint16_t)(lsb))
166
167/* Macro to set bits */
168#define BME68X_SET_BITS(reg_data, bitname, data) \
169    (((reg_data) & ~(bitname##_MSK)) | \
170    (((data) << bitname##_POS) & bitname##_MSK))
171
172/* Macro to set bits starting from position 0 */
173#define BME68X_SET_BITS_POS_0(reg_data, bitname, data) \
174    (((reg_data) & ~(bitname##_MSK)) | ((data) & bitname##_MSK))
175
176struct Bme688CalibData {
177    /*! Calibration coefficient for the humidity sensor */
178    uint16_t par_h1;
179
180    /*! Calibration coefficient for the humidity sensor */
181    uint16_t par_h2;
182
183    /*! Calibration coefficient for the humidity sensor */
184    int8_t par_h3;
185
186    /*! Calibration coefficient for the humidity sensor */
187    int8_t par_h4;
188
189    /*! Calibration coefficient for the humidity sensor */
190    int8_t par_h5;
191
192    /*! Calibration coefficient for the humidity sensor */
193    uint8_t par_h6;
194
195    /*! Calibration coefficient for the humidity sensor */
196    int8_t par_h7;
197
198    /*! Calibration coefficient for the gas sensor */
199    int8_t par_gh1;
200
201    /*! Calibration coefficient for the gas sensor */
202    int16_t par_gh2;
203
204    /*! Calibration coefficient for the gas sensor */
205    int8_t par_gh3;
206
207    /*! Calibration coefficient for the temperature sensor */
208    uint16_t par_t1;
209
210    /*! Calibration coefficient for the temperature sensor */
211    int16_t par_t2;
212
213    /*! Calibration coefficient for the temperature sensor */
214    int8_t par_t3;
215
216    /*! Calibration coefficient for the pressure sensor */
217    uint16_t par_p1;
218
219    /*! Calibration coefficient for the pressure sensor */
220    int16_t par_p2;
221
222    /*! Calibration coefficient for the pressure sensor */
223    int8_t par_p3;
224
225    /*! Calibration coefficient for the pressure sensor */
226    int16_t par_p4;
227
228    /*! Calibration coefficient for the pressure sensor */
229    int16_t par_p5;
230
231    /*! Calibration coefficient for the pressure sensor */
232    int8_t par_p6;
233
234    /*! Calibration coefficient for the pressure sensor */
235    int8_t par_p7;
236
237    /*! Calibration coefficient for the pressure sensor */
238    int16_t par_p8;
239
240    /*! Calibration coefficient for the pressure sensor */
241    int16_t par_p9;
242
243    /*! Calibration coefficient for the pressure sensor */
244    uint8_t par_p10;
245
246    /*! Variable to store the intermediate temperature coefficient */
247    int32_t t_fine;
248
249    /*! Heater resistance range coefficient */
250    uint8_t res_heat_range;
251
252    /*! Heater resistance value coefficient */
253    int8_t res_heat_val;
254
255    /*! Gas resistance range switching error coefficient */
256    int8_t range_sw_err;
257};
258
259struct bme688HeatrConf {
260    /*! Enable gas measurement. Refer @ref en_dis */
261    uint8_t enable;
262
263    /*! Store the heater temperature for forced mode degree Celsius */
264    uint16_t heatr_temp;
265
266    /*! Store the heating duration for forced mode in milliseconds */
267    uint16_t heatr_dur;
268
269    /*! Store the heater temperature profile in degree Celsius */
270    uint16_t *heatr_temp_prof;
271
272    /*! Store the heating duration profile in milliseconds */
273    uint16_t *heatr_dur_prof;
274
275    /*! Variable to store the length of the heating profile */
276    uint8_t profile_len;
277
278    /*!
279     * Variable to store heating duration for parallel mode
280     * in milliseconds
281     */
282    uint16_t shared_heatr_dur;
283};
284
285struct Bme688Status {
286    int8_t variantId;
287    int8_t workState;
288    int8_t inited;
289};
290
291struct Bme688DrvData {
292    struct IDeviceIoService ioService;
293    struct HdfDeviceObject *device;
294    struct SensorCfgData *sensorCfg;
295};
296
297enum Bme688FieldData {
298    RESISTANCE = 0,
299    TEMPERATURE = 1,
300    HUMIDITY = 2,
301    PRESSURE = 3
302};
303
304#endif /* BME688_H */
305
306