1 /**
2 * Copyright (c) 2024 Bosch Sensortec GmbH. All rights reserved.
3 *
4 * gas_bme688_driver.c 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 #include "gas_bme688_driver.h"
11 #include "osal_mem.h"
12 #include "osal_time.h"
13 #include "sensor_config_controller.h"
14 #include "sensor_device_manager.h"
15 #include "sensor_gas_driver.h"
16 #include <securec.h>
17
18 #define HDF_LOG_TAG hdf_sensor_gas
19
20 /* This internal API is used to calculate the temperature in integer */
21 static int16_t BmeHalCalcTemperature(struct SensorCfgData *data, uint32_t tempAdc);
22
23 /* This internal API is used to calculate the pressure value in integer */
24 static uint32_t BmeHalCalcPressure(struct SensorCfgData *data, uint32_t presAdc);
25
26 /* This internal API is used to calculate the humidity value in integer */
27 static uint32_t BmeHalCalcHumidity(struct SensorCfgData *data, uint16_t humADC);
28
29 /* This internal API is used to calculate the gas resistance high value in integer */
30 static uint32_t BmeHalCalcGasResistanceHigh(uint16_t gasResAdc, uint8_t gasRange);
31
32 /* This internal API is used to calculate the gas resistance low value in integer */
33 static uint32_t BmeHalCalcGasResistanceLow(struct SensorCfgData *data,
34 uint16_t gasResAdc, uint8_t gasRange);
35
36 /* This internal API is used to calculate the heater resistance value using integer */
37 static uint8_t BmeHalCalcResHeat(struct SensorCfgData *data, uint16_t temp);
38
39 /* This internal API is used to set gas wait and resistance heat config using integer*/
40 static int32_t BmeHalSetConfig(struct SensorCfgData *data,
41 struct bme688HeatrConf *conf, uint8_t opMode, uint8_t *nbConv);
42
43 /* This internal API is used to calculate the gas wait */
44 static uint8_t BmeHalCalcGasWait(uint16_t dur);
45
46 /* This internal API is used to read a single data of the sensor */
47 static int32_t BmeHalReadFieldData(struct SensorCfgData *data, uint8_t index,
48 struct GasFieldData *fieldData);
49
50 /* This internal API is used to get operation mode */
51 static int32_t Bme688GetOpMode(struct SensorCfgData *data, uint8_t *opMode);
52
53 /* This internal API is used to set operation mode */
54 static int32_t Bme688SetOpMode(struct SensorCfgData *data, const uint8_t opMode);
55
56 /* This internal API is used to get measurement duration */
57 static uint32_t Bme688GetMeasDur(struct SensorCfgData *data, const uint8_t opMode,
58 struct GasCfg *gascfg);
59
60 /* This internal API is used to set configuration */
61 static int32_t Bme688SetConfig(struct SensorCfgData *data, struct GasCfg *gascfg);
62
63 /* This internal API is used to set heatr configuration */
64 static int32_t Bme688SetHeatrConfig(struct SensorCfgData *data, struct bme688HeatrConf *conf,
65 uint8_t opMode);
66
67 /* This internal API is used to limit the max value of a parameter */
68 static int32_t BmeHalBoundaryCheck(struct SensorCfgData *data, uint8_t *value, uint8_t max);
69
70 /* This internal API is used to read the sensor data */
71 static int32_t Bme688GetData(struct SensorCfgData *data, struct GasFieldData *fieldData,
72 uint8_t opMode);
73
74 static struct Bme688DrvData *g_bme688DrvData = NULL;
75 static struct Bme688CalibData g_calibData;
76 static int16_t reTemp = 0;
77 static uint32_t reData[4] = {0};
78 static struct Bme688Status g_bme688State;
79
Bme688GetDrvData(void)80 static struct Bme688DrvData *Bme688GetDrvData(void)
81 {
82 return g_bme688DrvData;
83 }
84
85 /// @brief basic register write one byte function
86 /// @param data Sensor configuration data structre pointer
87 /// @param rega register address
88 /// @param buffer value to write
89 /// @return HDF_SUCCESS if success, failed any error
BmeHalRegWriteOneByte(struct SensorCfgData * data,uint8_t rega,uint8_t buffer)90 static int32_t BmeHalRegWriteOneByte(struct SensorCfgData *data, uint8_t rega, uint8_t buffer)
91 {
92 int32_t rc = HDF_SUCCESS;
93 int32_t index = 0;
94 uint8_t g_regw_buffer[20];
95 uint8_t len = 1;
96 (void)memset_s(g_regw_buffer, sizeof(g_regw_buffer), 0, sizeof(g_regw_buffer));
97
98 CHECK_NULL_PTR_RETURN_VALUE(data, HDF_ERR_INVALID_PARAM);
99
100 g_regw_buffer[0] = (rega & 0xFF);
101 do {
102 g_regw_buffer[index + 1] = buffer;
103 index ++;
104 } while (index < len);
105
106 rc = WriteSensor(&data->busCfg, g_regw_buffer, (len + 1));
107 OsalUDelay(BME688_DELAY_10);
108
109 if (rc != HDF_SUCCESS) {
110 HDF_LOGE("%s: [BME688] w reg:%d err:%d", __func__, rega, rc);
111 }
112
113 return rc;
114 }
115
116 /// @brief basic register write multiply byte function
117 /// @param data Sensor configuration data structre pointer
118 /// @param rega register address
119 /// @param buffer value to write
120 /// @param len write len
121 /// @return HDF_SUCCESS if success, failed any error
BmeHalRegWriteMulByte(struct SensorCfgData * data,uint8_t * rega,uint8_t * buffer,uint32_t len)122 static int32_t BmeHalRegWriteMulByte(struct SensorCfgData *data, uint8_t *rega, uint8_t *buffer, uint32_t len)
123 {
124 int32_t rc = HDF_SUCCESS;
125 int32_t index = 0;
126
127 CHECK_NULL_PTR_RETURN_VALUE(data, HDF_ERR_INVALID_PARAM);
128
129 do {
130 rc = BmeHalRegWriteOneByte(data, rega[index], buffer[index]);
131 index ++;
132 } while (index < len);
133
134 return rc;
135 }
136
137 /// @brief basic register read function
138 /// @param data Sensor configuration data structre pointer
139 /// @param rega register address to read
140 /// @param buffer read data buffer
141 /// @param len read len
142 /// @return HDF_SUCCESS if success, failed any error
BmeHalRegRead(struct SensorCfgData * data,uint16_t rega,uint8_t * buffer,uint32_t len)143 static int32_t BmeHalRegRead(struct SensorCfgData *data, uint16_t rega, uint8_t *buffer, uint32_t len)
144 {
145 int32_t rc = HDF_SUCCESS;
146
147 rc = ReadSensor(&data->busCfg, rega, buffer, len);
148 if (rc != HDF_SUCCESS) {
149 HDF_LOGE("%s: [BME688] r reg:%d err", __func__, rega);
150 }
151 OsalUDelay(BME688_DELAY_4);
152
153 return rc;
154 }
155
Bme688HalReadSensorRawData(struct SensorCfgData * data,struct GasData * rawData)156 static int32_t Bme688HalReadSensorRawData(struct SensorCfgData *data, struct GasData *rawData)
157 {
158 struct GasFieldData fieldData = { 0 };
159 uint8_t opMode = 0;
160 int32_t ret = HDF_SUCCESS;
161
162 CHECK_NULL_PTR_RETURN_VALUE(data, HDF_ERR_INVALID_PARAM);
163 CHECK_NULL_PTR_RETURN_VALUE(rawData, HDF_ERR_INVALID_PARAM);
164
165 ret = Bme688GetOpMode(data, &opMode);
166 if ((opMode & BME68X_MODE_MSK) == BME68X_SLEEP_MODE) {
167 ret = Bme688GetData(data, &fieldData, BME68X_FORCED_MODE);
168
169 g_bme688State.workState = BME688_WORK_MODE_SUSPEND;
170
171 rawData->gasResitance = fieldData.gas_resistance;
172 rawData->heatSource = BME688_HEATR_TEMP;
173 rawData->temperature = fieldData.temperature;
174 rawData->humidity = fieldData.humidity;
175 rawData->pressure = fieldData.pressure;
176
177 reData[RESISTANCE] = fieldData.gas_resistance;
178 reData[TEMPERATURE] = BME688_HEATR_TEMP;
179 reTemp = fieldData.temperature;
180 reData[HUMIDITY] = fieldData.humidity;
181 reData[PRESSURE] = fieldData.pressure;
182 } else if ((opMode & BME68X_MODE_MSK) == BME68X_FORCED_MODE) {
183 rawData->gasResitance = reData[RESISTANCE];
184 rawData->heatSource = reData[TEMPERATURE];
185 rawData->temperature = reTemp;
186 rawData->humidity = reData[HUMIDITY];
187 rawData->pressure = reData[PRESSURE];
188 } else {
189 HDF_LOGE("%s: opMode ERROR!", __func__);
190 return HDF_FAILURE;
191 }
192
193 return ret;
194 }
195
196 /// @brief basic register write function
197 /// @param data Sensor configuration data structre pointer
198 /// @param rawData The raw data buffer need to read
199 /// @param timestamp timestamp when reading data
200 /// @return HDF_SUCCESS if success, failed any others error
ReadBme688RawData(struct SensorCfgData * data,struct GasData * rawData,int64_t * timestamp)201 static int32_t ReadBme688RawData(struct SensorCfgData *data, struct GasData *rawData, int64_t *timestamp)
202 {
203 OsalTimespec time;
204 uint8_t regv[GAS_PART_SUM] = {0};
205 int32_t ret = HDF_SUCCESS;
206 struct GasCfg conf;
207 struct bme688HeatrConf heatConf;
208 (void)memset_s(&time, sizeof(time), 0, sizeof(time));
209 (void)memset_s(regv, sizeof(regv), 0, sizeof(regv));
210
211 CHECK_NULL_PTR_RETURN_VALUE(data, HDF_ERR_INVALID_PARAM);
212 CHECK_NULL_PTR_RETURN_VALUE(rawData, HDF_ERR_INVALID_PARAM);
213 CHECK_NULL_PTR_RETURN_VALUE(timestamp, HDF_ERR_INVALID_PARAM);
214
215 if (OsalGetTime(&time) != HDF_SUCCESS) {
216 HDF_LOGE("%s: Get time failed", __func__);
217 return HDF_FAILURE;
218 }
219 *timestamp = time.sec * SENSOR_SECOND_CONVERT_NANOSECOND + time.usec * SENSOR_CONVERT_UNIT; /* unit nanosecond */
220
221 if (g_bme688State.workState == BME688_WORK_MODE_SUSPEND) {
222 if (g_bme688State.inited != BME68X_ENABLE) {
223 conf.humOs = BME68X_OS_16X;
224 conf.tempOs = BME68X_OS_2X;
225 conf.presOs = BME68X_OS_1X;
226 conf.filter = BME68X_FILTER_OFF;
227 conf.odr = BME68X_ODR_NONE;
228
229 ret = Bme688SetConfig(data, &conf);
230 if (ret != HDF_SUCCESS) {
231 HDF_LOGE("%s: bme688 sensor set oversample config failed", __func__);
232 return HDF_FAILURE;
233 }
234
235 heatConf.enable = BME68X_ENABLE;
236 heatConf.heatr_temp = BME688_HEATR_TEMP;
237 heatConf.heatr_dur = BME688_HEATR_DUR;
238
239 ret = Bme688SetHeatrConfig(data, &heatConf, BME68X_FORCED_MODE);
240 g_bme688State.inited = BME68X_ENABLE;
241 }
242
243 ret = Bme688SetOpMode(data, BME68X_FORCED_MODE);
244 g_bme688State.workState = BME688_WORK_MODE_IDLE;
245 }
246
247 if (g_bme688State.workState == BME688_WORK_MODE_IDLE) {
248 ret = Bme688HalReadSensorRawData(data, rawData);
249 }
250
251 return ret;
252 }
253
254 /* read bme688 sensor data */
ReadBme688Data(struct SensorCfgData * cfg,struct SensorReportEvent * event)255 static int32_t ReadBme688Data(struct SensorCfgData *cfg, struct SensorReportEvent *event)
256 {
257 int32_t ret = HDF_SUCCESS;
258 struct GasData rawData = {0};
259 static int16_t tmp[GAS_DEP_PART_SUM] = {0};
260
261 CHECK_NULL_PTR_RETURN_VALUE(cfg, HDF_ERR_INVALID_PARAM);
262 CHECK_NULL_PTR_RETURN_VALUE(event, HDF_ERR_INVALID_PARAM);
263
264 ret = ReadBme688RawData(cfg, &rawData, (int64_t *)&event->timestamp);
265 if (ret != HDF_SUCCESS) {
266 HDF_LOGE("%s: bme688 read raw data failed", __func__);
267 return HDF_FAILURE;
268 }
269 event->sensorId = SENSOR_TAG_GAS;
270 event->option = 0;
271 event->mode = SENSOR_WORK_MODE_REALTIME;
272
273 HDF_LOGI("%s rawData->gasResitance = %d", __func__, rawData.gasResitance);
274 HDF_LOGI("%s rawData->heatSource = %d", __func__, rawData.heatSource);
275 HDF_LOGI("%s rawData->temperature = %d", __func__, rawData.temperature);
276 HDF_LOGI("%s rawData->humidity = %d", __func__, rawData.humidity);
277 HDF_LOGI("%s rawData->pressure = %d", __func__, rawData.pressure);
278
279 tmp[GAS_PART_GASRES] = rawData.gasResitance;
280 tmp[GAS_PART_HEAT] = rawData.heatSource;
281 tmp[GAS_PART_TEMP] = rawData.temperature;
282 tmp[GAS_PART_HUMI] = rawData.humidity;
283 tmp[GAS_PART_PRE] = rawData.pressure;
284
285 event->dataLen = sizeof(tmp);
286 event->data = (uint8_t *)&tmp;
287
288 return ret;
289 }
290
291 /* This internal API is used to soft reset sensor */
Bme688SoftReset(struct SensorCfgData * data)292 static int32_t Bme688SoftReset(struct SensorCfgData *data)
293 {
294 int32_t rc;
295 uint8_t regv = BME68X_SOFT_RESET_CMD;
296
297 CHECK_NULL_PTR_RETURN_VALUE(data, HDF_ERR_INVALID_PARAM);
298
299 rc = BmeHalRegWriteOneByte(data, BME68X_REG_SOFT_RESET, regv);
300 if (rc != HDF_SUCCESS) {
301 HDF_LOGE("%s: bme688 write command register failed", __func__);
302 return HDF_FAILURE;
303 }
304
305 OsalMDelay(BME688_DELAY_5); /* delay 5ms after reset */
306
307 return rc;
308 }
309
310 /* This internal API is used to validate chip id */
Bme688ValChipId(struct SensorCfgData * data)311 static int32_t Bme688ValChipId(struct SensorCfgData *data)
312 {
313 uint8_t regv = 0;
314 int32_t rc = HDF_SUCCESS;
315
316 rc = BmeHalRegRead(data, BME68X_REG_CHIP_ID, ®v, 1);
317 if (rc != HDF_SUCCESS) {
318 HDF_LOGE("%s: [BME688] WARN!!, NO Sensor", __func__);
319 return HDF_FAILURE;
320 }
321
322 HDF_LOGI("%s: rc = %d, WHO_AMI: 0x%x", __func__, rc, regv);
323
324 if (regv != BME68X_CHIP_ID) {
325 rc = HDF_DEV_ERR_NO_DEVICE;
326 }
327
328 return rc;
329 }
330
331 /* This internal API is used to read variant id */
Bme688ReadVariantId(struct SensorCfgData * data)332 static int32_t Bme688ReadVariantId(struct SensorCfgData *data)
333 {
334 uint8_t regv = 0;
335 int32_t rc = HDF_SUCCESS;
336
337 rc = BmeHalRegRead(data, BME68X_REG_VARIANT_ID, ®v, 1);
338 if (rc != HDF_SUCCESS) {
339 HDF_LOGE("%s: [BME688] read variant id failed", __func__);
340 return HDF_FAILURE;
341 }
342 HDF_LOGI("%s: rc = %d, regv = 0x%x", __func__, rc, regv);
343 g_bme688State.variantId = regv;
344
345 return rc;
346 }
347
348 /* function calculate the coeff from register to local before sensor data calibration */
Bme688GetCofParam(struct Bme688CalibData * myCalibData,uint8_t * coeff_array)349 static void Bme688GetCofParam(struct Bme688CalibData *myCalibData, uint8_t* coeff_array)
350 {
351 /* Temperature related coefficients */
352 myCalibData->par_t1 =
353 (uint16_t)(BME68X_CONCAT_BYTES(coeff_array[BME68X_IDX_T1_MSB], coeff_array[BME68X_IDX_T1_LSB]));
354 myCalibData->par_t2 =
355 (int16_t)(BME68X_CONCAT_BYTES(coeff_array[BME68X_IDX_T2_MSB], coeff_array[BME68X_IDX_T2_LSB]));
356 myCalibData->par_t3 =
357 (int8_t)(coeff_array[BME68X_IDX_T3]);
358
359 /* Pressure related coefficients */
360 myCalibData->par_p1 =
361 (uint16_t)(BME68X_CONCAT_BYTES(coeff_array[BME68X_IDX_P1_MSB], coeff_array[BME68X_IDX_P1_LSB]));
362 myCalibData->par_p2 =
363 (int16_t)(BME68X_CONCAT_BYTES(coeff_array[BME68X_IDX_P2_MSB], coeff_array[BME68X_IDX_P2_LSB]));
364 myCalibData->par_p3 = (int8_t)coeff_array[BME68X_IDX_P3];
365 myCalibData->par_p4 =
366 (int16_t)(BME68X_CONCAT_BYTES(coeff_array[BME68X_IDX_P4_MSB], coeff_array[BME68X_IDX_P4_LSB]));
367 myCalibData->par_p5 =
368 (int16_t)(BME68X_CONCAT_BYTES(coeff_array[BME68X_IDX_P5_MSB], coeff_array[BME68X_IDX_P5_LSB]));
369 myCalibData->par_p6 = (int8_t)(coeff_array[BME68X_IDX_P6]);
370 myCalibData->par_p7 = (int8_t)(coeff_array[BME68X_IDX_P7]);
371 myCalibData->par_p8 =
372 (int16_t)(BME68X_CONCAT_BYTES(coeff_array[BME68X_IDX_P8_MSB], coeff_array[BME68X_IDX_P8_LSB]));
373 myCalibData->par_p9 =
374 (int16_t)(BME68X_CONCAT_BYTES(coeff_array[BME68X_IDX_P9_MSB], coeff_array[BME68X_IDX_P9_LSB]));
375 myCalibData->par_p10 = (uint8_t)(coeff_array[BME68X_IDX_P10]);
376
377 /* Humidity related coefficients */
378 myCalibData->par_h1 =
379 (uint16_t)(((uint16_t)coeff_array[BME68X_IDX_H1_MSB] << 4) |
380 (coeff_array[BME68X_IDX_H1_LSB] & BME68X_BIT_H1_DATA_MSK));
381 myCalibData->par_h2 =
382 (uint16_t)(((uint16_t)coeff_array[BME68X_IDX_H2_MSB] << 4) | ((coeff_array[BME68X_IDX_H2_LSB]) >> 4));
383 myCalibData->par_h3 = (int8_t)coeff_array[BME68X_IDX_H3];
384 myCalibData->par_h4 = (int8_t)coeff_array[BME68X_IDX_H4];
385 myCalibData->par_h5 = (int8_t)coeff_array[BME68X_IDX_H5];
386 myCalibData->par_h6 = (uint8_t)coeff_array[BME68X_IDX_H6];
387 myCalibData->par_h7 = (int8_t)coeff_array[BME68X_IDX_H7];
388
389 /* Gas heater related coefficients */
390 myCalibData->par_gh1 = (int8_t)coeff_array[BME68X_IDX_GH1];
391 myCalibData->par_gh2 =
392 (int16_t)(BME68X_CONCAT_BYTES(coeff_array[BME68X_IDX_GH2_MSB], coeff_array[BME68X_IDX_GH2_LSB]));
393 myCalibData->par_gh3 = (int8_t)coeff_array[BME68X_IDX_GH3];
394
395 /* Other coefficients */
396 myCalibData->res_heat_range = ((coeff_array[BME68X_IDX_RES_HEAT_RANGE] & BME68X_RHRANGE_MSK) / 16);
397 myCalibData->res_heat_val = (int8_t)coeff_array[BME68X_IDX_RES_HEAT_VAL];
398 myCalibData->range_sw_err = ((int8_t)(coeff_array[BME68X_IDX_RANGE_SW_ERR] & BME68X_RSERROR_MSK)) / 16;
399 }
400
401 /* This internal API is used to get calibration data */
Bme688GetCalibData(struct SensorCfgData * data,struct Bme688CalibData * calibData)402 static int32_t Bme688GetCalibData(struct SensorCfgData *data,
403 struct Bme688CalibData *calibData)
404 {
405 int32_t rc = HDF_SUCCESS;
406 uint8_t coeff_array[BME68X_LEN_COEFF_ALL] = {0};
407
408 rc = BmeHalRegRead(data, BME68X_REG_COEFF1, coeff_array, BME68X_LEN_COEFF1);
409 if (rc != HDF_SUCCESS) {
410 HDF_LOGE("%s: [BME688] read data from BME68X_REG_COEFF1 failed", __func__);
411 return HDF_FAILURE;
412 }
413
414 rc = BmeHalRegRead(data, BME68X_REG_COEFF2, &coeff_array[BME68X_LEN_COEFF1], BME68X_LEN_COEFF2);
415 if (rc != HDF_SUCCESS) {
416 HDF_LOGE("%s: [BME688] read data from BME68X_REG_COEFF2 failed", __func__);
417 return HDF_FAILURE;
418 }
419
420 rc = BmeHalRegRead(data, BME68X_REG_COEFF3, &coeff_array[BME68X_LEN_COEFF1 + BME68X_LEN_COEFF2], BME68X_LEN_COEFF3);
421 if (rc != HDF_SUCCESS) {
422 HDF_LOGE("%s: [BME688] read data from BME68X_REG_COEFF3 failed", __func__);
423 return HDF_FAILURE;
424 }
425
426 Bme688GetCofParam(calibData, coeff_array);
427
428 return rc;
429 }
430
Bme688GetOpMode(struct SensorCfgData * data,uint8_t * opMode)431 static int32_t Bme688GetOpMode(struct SensorCfgData *data, uint8_t *opMode)
432 {
433 int32_t rc = HDF_SUCCESS;
434 uint8_t mode;
435
436 CHECK_NULL_PTR_RETURN_VALUE(opMode, HDF_ERR_INVALID_PARAM);
437
438 rc = BmeHalRegRead(data, BME68X_REG_CTRL_MEAS, &mode, 1);
439 *opMode = mode & BME68X_MODE_MSK;
440
441 return rc;
442 }
443
Bme688SetOpMode(struct SensorCfgData * data,const uint8_t opMode)444 static int32_t Bme688SetOpMode(struct SensorCfgData *data, const uint8_t opMode)
445 {
446 int32_t rc;
447 uint8_t tmpPowMode = 0;
448 uint8_t powMode = 0;
449 uint8_t regAddr = BME68X_REG_CTRL_MEAS;
450
451 do {
452 rc = BmeHalRegRead(data, regAddr, &tmpPowMode, 1);
453 if (rc != HDF_SUCCESS) {
454 HDF_LOGE("%s: [BME688] get power mode failed", __func__);
455 }
456 powMode = tmpPowMode & BME68X_MODE_MSK;
457 if (powMode != BME68X_SLEEP_MODE) {
458 tmpPowMode &= ~BME68X_MODE_MSK;
459 rc = BmeHalRegWriteOneByte(data, regAddr, tmpPowMode);
460 OsalMDelay(BME688_DELAY_10);
461 }
462 } while (powMode != BME68X_SLEEP_MODE && rc == HDF_SUCCESS);
463
464 if (opMode != BME68X_SLEEP_MODE && rc == HDF_SUCCESS) {
465 tmpPowMode = (tmpPowMode & ~BME68X_MODE_MSK) | (opMode & BME68X_MODE_MSK);
466 rc = BmeHalRegWriteOneByte(data, regAddr, tmpPowMode);
467 }
468
469 return rc;
470 }
471
BmeHalCalcTemperature(struct SensorCfgData * data,uint32_t tempAdc)472 static int16_t BmeHalCalcTemperature(struct SensorCfgData *data, uint32_t tempAdc)
473 {
474 int64_t var1;
475 int64_t var2;
476 int64_t var3;
477 int16_t calcTemp;
478
479 var1 = ((int32_t)tempAdc >> 3) - ((int32_t)g_calibData.par_t1 << 1);
480 var2 = (var1 * (int32_t)g_calibData.par_t2) >> 11;
481 var3 = ((var1 >> 1) * (var1 >> 1)) >> 12;
482 var3 = ((var3) * ((int32_t)g_calibData.par_t3 << 4)) >> 14;
483 g_calibData.t_fine = (int32_t)(var2 + var3);
484 calcTemp = (int16_t)(((g_calibData.t_fine * 5) + 128) >> 8);
485
486 /*measurement unit : degrees centigrade*/
487 return calcTemp / 100;
488 }
489
BmeHalCalcPressure(struct SensorCfgData * data,uint32_t presAdc)490 static uint32_t BmeHalCalcPressure(struct SensorCfgData *data, uint32_t presAdc)
491 {
492 int32_t var1;
493 int32_t var2;
494 int32_t var3;
495 int32_t pressureComp;
496
497 const int32_t pres_ovf_check = BME_INT32_C(0x40000000);
498
499 /*lint -save -e701 -e702 -e713 */
500 var1 = (((int32_t)g_calibData.t_fine) >> 1) - 64000;
501 var2 = ((((var1 >> 2) * (var1 >> 2)) >> 11) * (int32_t)g_calibData.par_p6) >> 2;
502 var2 = var2 + ((var1 * (int32_t)g_calibData.par_p5) << 1);
503 var2 = (var2 >> 2) + ((int32_t)g_calibData.par_p4 << 16);
504 var1 = (((((var1 >> 2) * (var1 >> 2)) >> 13) * ((int32_t)g_calibData.par_p3 << 5)) >> 3) +
505 (((int32_t)g_calibData.par_p2 * var1) >> 1);
506 var1 = var1 >> 18;
507 var1 = ((32768 + var1) * (int32_t)g_calibData.par_p1) >> 15;
508 pressureComp = 1048576 - presAdc;
509 pressureComp = (int32_t)((pressureComp - (var2 >> 12)) * ((uint32_t)3125));
510 if (pressureComp >= pres_ovf_check) {
511 pressureComp = ((pressureComp / var1) << 1);
512 } else {
513 pressureComp = ((pressureComp << 1) / var1);
514 }
515
516 var1 = ((int32_t)g_calibData.par_p9 * (int32_t)(((pressureComp >> 3) * (pressureComp >> 3)) >> 13)) >> 12;
517 var2 = ((int32_t)(pressureComp >> 2) * (int32_t)g_calibData.par_p8) >> 13;
518 var3 = ((int32_t)(pressureComp >> 8) * (int32_t)(pressureComp >> 8) * (int32_t)(pressureComp >> 8) *
519 (int32_t)g_calibData.par_p10) >> 17;
520 pressureComp = (int32_t)(pressureComp) + ((var1 + var2 + var3 + ((int32_t)g_calibData.par_p7 << 7)) >> 4);
521
522 /*lint -restore */
523 /*measurement unit : kPa*/
524 return (uint32_t)pressureComp / 100;
525 }
526
BmeHalCalcHumidity(struct SensorCfgData * data,uint16_t humADC)527 static uint32_t BmeHalCalcHumidity(struct SensorCfgData *data, uint16_t humADC)
528 {
529 int32_t var1;
530 int32_t var2;
531 int32_t var3;
532 int32_t var4;
533 int32_t var5;
534 int32_t var6;
535 int32_t tempScaled;
536 int32_t calcHum;
537
538 /*lint -save -e702 -e704 */
539 tempScaled = (((int32_t)g_calibData.t_fine * 5) + 128) >> 8;
540 var1 = (int32_t)(humADC - ((int32_t)((int32_t)g_calibData.par_h1 * 16))) -
541 (((tempScaled * (int32_t)g_calibData.par_h3) / ((int32_t)100)) >> 1);
542 var2 =
543 ((int32_t)g_calibData.par_h2 *
544 (((tempScaled * (int32_t)g_calibData.par_h4) / ((int32_t)100)) +
545 (((tempScaled * ((tempScaled * (int32_t)g_calibData.par_h5) / ((int32_t)100))) >> 6) / ((int32_t)100)) +
546 (int32_t)(1 << 14))) >> 10;
547 var3 = var1 * var2;
548 var4 = (int32_t)g_calibData.par_h6 << 7;
549 var4 = ((var4) + ((tempScaled * (int32_t)g_calibData.par_h7) / ((int32_t)100))) >> 4;
550 var5 = ((var3 >> 14) * (var3 >> 14)) >> 10;
551 var6 = (var4 * var5) >> 1;
552
553 calcHum = (((var3 + var6) >> 10) * ((int32_t)1000)) >> 12;
554
555 /* Cap at 100%rH */
556 if (calcHum > BME688_MAX_HUM) {
557 calcHum = BME688_MAX_HUM;
558 } else if (calcHum < 0) {
559 calcHum = 0;
560 }
561
562 /*lint -restore */
563 /*measurement unit : Integer*/
564 return (uint32_t)calcHum / 1000;
565 }
566
BmeHalCalcGasResistanceHigh(uint16_t gasResAdc,uint8_t gasRange)567 static uint32_t BmeHalCalcGasResistanceHigh(uint16_t gasResAdc, uint8_t gasRange)
568 {
569 uint32_t calc_gas_res;
570 uint32_t var1 = BME_UINT32_C(262144) >> gasRange;
571 int32_t var2 = (int32_t)gasResAdc - BME_INT32_C(512);
572
573 var2 *= BME_INT32_C(3);
574 var2 = BME_INT32_C(4096) + var2;
575
576 /* multiplying 10000 then dividing then multiplying by 100 instead of multiplying by 1000000 to prevent overflow */
577 calc_gas_res = (BME_UINT32_C(10000) * var1) / (uint32_t)var2;
578 calc_gas_res = calc_gas_res * 100;
579
580 return calc_gas_res;
581 }
582
BmeHalCalcGasResistanceLow(struct SensorCfgData * data,uint16_t gasResAdc,uint8_t gasRange)583 static uint32_t BmeHalCalcGasResistanceLow(struct SensorCfgData *data,
584 uint16_t gasResAdc, uint8_t gasRange)
585 {
586 int64_t var1;
587 uint64_t var2;
588 int64_t var3;
589 uint32_t calc_gas_res;
590 uint32_t lookup_table1[16] = {
591 BME_UINT32_C(2147483647), BME_UINT32_C(2147483647), BME_UINT32_C(2147483647),
592 BME_UINT32_C(2147483647), BME_UINT32_C(2147483647), BME_UINT32_C(2126008810),
593 BME_UINT32_C(2147483647), BME_UINT32_C(2130303777), BME_UINT32_C(2147483647),
594 BME_UINT32_C(2147483647), BME_UINT32_C(2143188679), BME_UINT32_C(2136746228),
595 BME_UINT32_C(2147483647), BME_UINT32_C(2126008810), BME_UINT32_C(2147483647),
596 BME_UINT32_C(2147483647)
597 };
598 uint32_t lookup_table2[16] = {
599 BME_UINT32_C(4096000000), BME_UINT32_C(2048000000), BME_UINT32_C(1024000000),
600 BME_UINT32_C(512000000), BME_UINT32_C(255744255), BME_UINT32_C(127110228),
601 BME_UINT32_C(64000000), BME_UINT32_C(32258064), BME_UINT32_C(16016016),
602 BME_UINT32_C(8000000), BME_UINT32_C(4000000), BME_UINT32_C(2000000),
603 BME_UINT32_C(1000000), BME_UINT32_C(500000), BME_UINT32_C(250000),
604 BME_UINT32_C(125000)
605 };
606
607 /*lint -save -e704 */
608 var1 = (int64_t)((1340 +
609 (5 * (int64_t)g_calibData.range_sw_err)) * ((int64_t)lookup_table1[gasRange])) >> 16;
610 var2 = (((int64_t)((int64_t)gasResAdc << 15) - (int64_t)(16777216)) + var1);
611 var3 = (((int64_t)lookup_table2[gasRange] * (int64_t)var1) >> 9);
612 calc_gas_res = (uint32_t)((var3 + ((int64_t)var2 >> 1)) / (int64_t)var2);
613
614 /*lint -restore */
615 return calc_gas_res;
616 }
617
BmeHalCalcResHeat(struct SensorCfgData * data,uint16_t temp)618 static uint8_t BmeHalCalcResHeat(struct SensorCfgData *data, uint16_t temp)
619 {
620 uint8_t heatr_res;
621 int32_t var1;
622 int32_t var2;
623 int32_t var3;
624 int32_t var4;
625 int32_t var5;
626 int32_t heatr_res_x100;
627
628 /* Cap temperature */
629 if (temp > BME688_MAX_TEMP) {
630 temp = BME688_MAX_TEMP;
631 }
632
633 var1 = (((int32_t)BME688_AMB_TEMP * g_calibData.par_gh3) / 1000) * 256;
634 var2 = (g_calibData.par_gh1 + 784) *
635 (((((g_calibData.par_gh2 + 154009) * temp * 5) / 100) + 3276800) / 10);
636 var3 = var1 + (var2 / 2);
637 var4 = (var3 / (g_calibData.res_heat_range + 4));
638 var5 = (131 * g_calibData.res_heat_val) + 65536;
639 heatr_res_x100 = (int32_t)(((var4 / var5) - 250) * 34);
640 heatr_res = (uint8_t)((heatr_res_x100 + 50) / 100);
641
642 return heatr_res;
643 }
644
BmeHalCalcGasWait(uint16_t dur)645 static uint8_t BmeHalCalcGasWait(uint16_t dur)
646 {
647 uint8_t factor = 0;
648 uint8_t durVal = 0;
649
650 if (dur > 0xfc0) {
651 durVal = 0xff;
652 } else {
653 while (dur > 0x3f) {
654 dur /= 4;
655 factor++;
656 }
657 durVal = (uint8_t)(dur + (factor * 64));
658 }
659
660 return durVal;
661 }
662
Bme688GetMeasDur(struct SensorCfgData * data,const uint8_t opMode,struct GasCfg * gascfg)663 static uint32_t Bme688GetMeasDur(struct SensorCfgData *data, const uint8_t opMode, struct GasCfg *gascfg)
664 {
665 int32_t ret = HDF_SUCCESS;
666 uint32_t meas_dur = 0; /* Calculate in us */
667 uint32_t meas_cycles = 0;
668 uint8_t os_to_meas_cycles[6] = { 0, 1, 2, 4, 8, 16 };
669
670 CHECK_NULL_PTR_RETURN_VALUE(gascfg, HDF_ERR_INVALID_PARAM);
671
672 ret = BmeHalBoundaryCheck(data, &gascfg->tempOs, BME68X_OS_16X);
673 ret = BmeHalBoundaryCheck(data, &gascfg->presOs, BME68X_OS_16X);
674 ret = BmeHalBoundaryCheck(data, &gascfg->humOs, BME68X_OS_16X);
675 if (ret != HDF_SUCCESS) {
676 HDF_LOGE("%s: [BME688] boundary check failed", __func__);
677 }
678
679 meas_cycles = os_to_meas_cycles[gascfg->tempOs];
680 meas_cycles += os_to_meas_cycles[gascfg->presOs];
681 meas_cycles += os_to_meas_cycles[gascfg->humOs];
682
683 /* TPH measurement duration */
684 meas_dur = meas_cycles * BME_UINT32_C(1963);
685 meas_dur += BME_UINT32_C(477 * 4); /* TPH switching duration */
686 meas_dur += BME_UINT32_C(477 * 5); /* Gas measurement duration */
687
688 if (opMode != BME68X_PARALLEL_MODE) {
689 meas_dur += BME_UINT32_C(1000); /* Wake up duration of 1ms */
690 }
691
692 return meas_dur;
693 }
694
BmeHalSetConfig(struct SensorCfgData * data,struct bme688HeatrConf * conf,uint8_t opMode,uint8_t * nbConv)695 static int32_t BmeHalSetConfig(struct SensorCfgData *data, struct bme688HeatrConf *conf,
696 uint8_t opMode, uint8_t *nbConv)
697 {
698 int32_t rc = HDF_SUCCESS;
699 uint8_t writeLen = 0;
700 uint8_t rh_reg_addr[10] = { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 };
701 uint8_t rh_reg_data[10] = { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 };
702 uint8_t gw_reg_addr[10] = { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 };
703 uint8_t gw_reg_data[10] = { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 };
704
705 switch (opMode) {
706 case BME68X_FORCED_MODE:
707 rh_reg_addr[0] = BME68X_REG_RES_HEAT0;
708 rh_reg_data[0] = BmeHalCalcResHeat(data, conf->heatr_temp);
709 gw_reg_addr[0] = BME68X_REG_GAS_WAIT0;
710 gw_reg_data[0] = BmeHalCalcGasWait(conf->heatr_dur);
711 (*nbConv) = 0;
712 writeLen = 1;
713 break;
714 default:
715 rc = HDF_ERR_INVALID_PARAM;
716 }
717
718 rc = BmeHalRegWriteOneByte(data, rh_reg_addr[0], rh_reg_data[0]);
719
720 rc = BmeHalRegWriteOneByte(data, gw_reg_addr[0], gw_reg_data[0]);
721
722 return rc;
723 }
724
Bme688SetHeatrConfig(struct SensorCfgData * data,struct bme688HeatrConf * conf,uint8_t opMode)725 static int32_t Bme688SetHeatrConfig(struct SensorCfgData *data, struct bme688HeatrConf *conf, uint8_t opMode)
726 {
727 int32_t rc;
728 uint8_t nb_conv = 0;
729 uint8_t hctrl = 0;
730 uint8_t run_gas = 0;
731 uint8_t ctrl_gas_data[2];
732 uint8_t ctrl_gas_addr[2] = { BME68X_REG_CTRL_GAS_0, BME68X_REG_CTRL_GAS_1 };
733
734 CHECK_NULL_PTR_RETURN_VALUE(conf, HDF_ERR_INVALID_PARAM);
735
736 rc = Bme688SetOpMode(data, BME68X_SLEEP_MODE);
737 rc = BmeHalSetConfig(data, conf, opMode, &nb_conv);
738 rc = BmeHalRegRead(data, BME68X_REG_CTRL_GAS_0, ctrl_gas_data, 2);
739
740 if (conf->enable == BME68X_ENABLE) {
741 hctrl = BME68X_ENABLE_HEATER;
742 if (g_bme688State.variantId == BME68X_VARIANT_GAS_HIGH) {
743 run_gas = BME68X_ENABLE_GAS_MEAS_H;
744 } else {
745 run_gas = BME68X_ENABLE_GAS_MEAS_L;
746 }
747 } else {
748 hctrl = BME68X_DISABLE_HEATER;
749 run_gas = BME68X_DISABLE_GAS_MEAS;
750 }
751
752 ctrl_gas_data[0] = BME68X_SET_BITS(ctrl_gas_data[0], BME68X_HCTRL, hctrl);
753 ctrl_gas_data[1] = BME68X_SET_BITS_POS_0(ctrl_gas_data[1], BME68X_NBCONV, nb_conv);
754 ctrl_gas_data[1] = BME68X_SET_BITS(ctrl_gas_data[1], BME68X_RUN_GAS, run_gas);
755
756 rc = BmeHalRegWriteMulByte(data, ctrl_gas_addr, ctrl_gas_data, 2);
757 return rc;
758 }
759
BmeHalBoundaryCheck(struct SensorCfgData * data,uint8_t * value,uint8_t max)760 static int32_t BmeHalBoundaryCheck(struct SensorCfgData *data, uint8_t *value, uint8_t max)
761 {
762 int32_t rc = HDF_SUCCESS;
763
764 CHECK_NULL_PTR_RETURN_VALUE(data, HDF_ERR_INVALID_PARAM);
765 if (value != NULL) {
766 if (*value > max) {
767 *value = max;
768 }
769 } else {
770 rc = HDF_ERR_INVALID_PARAM;
771 }
772
773 return rc;
774 }
775
PerformBoundaryChecks(struct SensorCfgData * data,struct GasCfg * gascfg)776 static int32_t PerformBoundaryChecks(struct SensorCfgData *data, struct GasCfg *gascfg)
777 {
778 int32_t rc;
779
780 rc = BmeHalBoundaryCheck(data, &gascfg->filter, BME68X_FILTER_SIZE_127);
781 if (rc != HDF_SUCCESS) {
782 return rc;
783 }
784
785 rc = BmeHalBoundaryCheck(data, &gascfg->tempOs, BME68X_OS_16X);
786 if (rc != HDF_SUCCESS) {
787 return rc;
788 }
789
790 rc = BmeHalBoundaryCheck(data, &gascfg->presOs, BME68X_OS_16X);
791 if (rc != HDF_SUCCESS) {
792 return rc;
793 }
794
795 rc = BmeHalBoundaryCheck(data, &gascfg->humOs, BME68X_OS_16X);
796 if (rc != HDF_SUCCESS) {
797 return rc;
798 }
799
800 rc = BmeHalBoundaryCheck(data, &gascfg->odr, BME68X_ODR_NONE);
801 if (rc != HDF_SUCCESS) {
802 return rc;
803 }
804
805 return HDF_SUCCESS;
806 }
807
ConfigureDataArray(uint8_t * dataArray,struct GasCfg * gascfg,uint8_t * odr20,uint8_t * odr3)808 static void ConfigureDataArray(uint8_t *dataArray, struct GasCfg *gascfg, uint8_t *odr20, uint8_t *odr3)
809 {
810 dataArray[4] = BME68X_SET_BITS(dataArray[4], BME68X_FILTER, gascfg->filter);
811 dataArray[3] = BME68X_SET_BITS(dataArray[3], BME68X_OST, gascfg->tempOs);
812 dataArray[3] = BME68X_SET_BITS(dataArray[3], BME68X_OSP, gascfg->presOs);
813 dataArray[1] = BME68X_SET_BITS_POS_0(dataArray[1], BME68X_OSH, gascfg->humOs);
814
815 if (gascfg->odr != BME68X_ODR_NONE) {
816 *odr20 = gascfg->odr;
817 *odr3 = 0;
818 }
819
820 dataArray[4] = BME68X_SET_BITS(dataArray[4], BME68X_ODR20, *odr20);
821 dataArray[0] = BME68X_SET_BITS(dataArray[0], BME68X_ODR3, *odr3);
822 }
823
ReadAdditionalRegisters(struct SensorCfgData * data,struct GasFieldData * fieldData)824 static int32_t ReadAdditionalRegisters(struct SensorCfgData* data, struct GasFieldData* fieldData)
825 {
826 int32_t rc = HDF_SUCCESS;
827 int32_t tempRc;
828
829 tempRc = BmeHalRegRead(data, BME68X_REG_RES_HEAT0 + fieldData->gas_index, &fieldData->res_heat, 1);
830 rc |= tempRc;
831
832 tempRc = BmeHalRegRead(data, BME68X_REG_IDAC_HEAT0 + fieldData->gas_index, &fieldData->idac, 1);
833 rc |= tempRc;
834
835 tempRc = BmeHalRegRead(data, BME68X_REG_GAS_WAIT0 + fieldData->gas_index, &fieldData->gas_wait, 1);
836 rc |= tempRc;
837
838 return rc;
839 }
840
Bme688SetConfigInternal(struct SensorCfgData * data,struct GasCfg * gascfg,int32_t * rc,uint8_t odr20,uint8_t odr3)841 static int32_t Bme688SetConfigInternal(struct SensorCfgData *data, struct GasCfg *gascfg,
842 int32_t *rc, uint8_t odr20, uint8_t odr3)
843 {
844 uint8_t regArray[BME68X_LEN_CONFIG];
845 uint8_t dataArray[BME68X_LEN_CONFIG] = {0};
846 uint8_t currentOpMode = 0;
847
848 regArray[0] = 0x71;
849 regArray[1] = 0x72;
850 regArray[2] = 0x73;
851 regArray[3] = 0x74;
852 regArray[4] = 0x75;
853
854 *rc = Bme688GetOpMode(data, ¤tOpMode);
855 if (*rc != HDF_SUCCESS) {
856 HDF_LOGE("%s: bme688 get operation mode failed", __func__);
857 return *rc;
858 }
859
860 *rc = Bme688SetOpMode(data, BME68X_SLEEP_MODE);
861 if (*rc != HDF_SUCCESS) {
862 HDF_LOGE("%s: bme688 set sleep mode failed", __func__);
863 return *rc;
864 }
865
866 *rc = BmeHalRegRead(data, regArray[0], dataArray, BME68X_LEN_CONFIG);
867 if (*rc != HDF_SUCCESS) {
868 HDF_LOGE("%s, line : %d, bme688 read data array failed", __func__, __LINE__);
869 return *rc;
870 }
871
872 *rc = PerformBoundaryChecks(data, gascfg);
873 if (*rc != HDF_SUCCESS) {
874 HDF_LOGE("%s: bme688 boundary check failed", __func__);
875 return *rc;
876 }
877
878 ConfigureDataArray(dataArray, gascfg, &odr20, &odr3);
879
880 *rc = BmeHalRegWriteMulByte(data, regArray, dataArray, BME68X_LEN_CONFIG);
881 if (*rc != HDF_SUCCESS) {
882 HDF_LOGE("%s: bme688 write config failed", __func__);
883 return *rc;
884 }
885
886 if (currentOpMode != BME68X_SLEEP_MODE) {
887 *rc = Bme688SetOpMode(data, currentOpMode);
888 if (*rc != HDF_SUCCESS) {
889 HDF_LOGE("%s: bme688 restore operation mode failed", __func__);
890 return *rc;
891 }
892 }
893
894 return *rc;
895 }
896
Bme688SetConfig(struct SensorCfgData * data,struct GasCfg * gascfg)897 static int32_t Bme688SetConfig(struct SensorCfgData *data, struct GasCfg *gascfg)
898 {
899 int32_t rc;
900 uint8_t odr20;
901 uint8_t odr3;
902
903 rc = HDF_SUCCESS;
904 odr20 = 0;
905 odr3 = 1;
906
907 CHECK_NULL_PTR_RETURN_VALUE(gascfg, HDF_ERR_INVALID_PARAM);
908
909 return Bme688SetConfigInternal(data, gascfg, &rc, odr20, odr3);
910 }
911
ParseSensorData(const uint8_t * buff,struct GasFieldData * fieldData,struct Bme688GasRawData * gasRawdata)912 static void ParseSensorData(const uint8_t* buff, struct GasFieldData* fieldData, struct Bme688GasRawData *gasRawdata)
913 {
914 fieldData->status = buff[0] & BME68X_NEW_DATA_MSK;
915 fieldData->gas_index = buff[0] & BME68X_GAS_INDEX_MSK;
916 fieldData->meas_index = buff[1];
917 gasRawData->adc_pres = ((uint32_t)buff[2] * 4096) | ((uint32_t)buff[3] * 16) | ((uint32_t)buff[4] / 16);
918 gasRawData->adc_temp = ((uint32_t)buff[5] * 4096) | ((uint32_t)buff[6] * 16) | ((uint32_t)buff[7] / 16);
919 gasRawData->adc_hum = ((uint32_t)buff[8] * 256) | (uint32_t)buff[9];
920 gasRawData->adc_gas_res_low = ((uint32_t)buff[13] * 4) | ((uint32_t)buff[14] / 64);
921 gasRawData->adc_gas_res_high = ((uint32_t)buff[15] * 4) | ((uint32_t)buff[16] / 64);
922 gasRawData->gas_range_l = buff[14] & BME68X_GAS_RANGE_MSK;
923 gasRawData->gas_range_h = buff[16] & BME68X_GAS_RANGE_MSK;
924 }
925
UpdateFieldDataStatus(struct GasFieldData * fieldData,uint8_t statusByte)926 static void UpdateFieldDataStatus(struct GasFieldData* fieldData, uint8_t statusByte)
927 {
928 fieldData->status |= statusByte & BME68X_GASM_VALID_MSK;
929 fieldData->status |= statusByte & BME68X_HEAT_STAB_MSK;
930 }
931
CalculateGasResistance(struct SensorCfgData * data,struct GasFieldData * fieldData,struct Bme688GasRawData * gasRawData)932 static void CalculateGasResistance(struct SensorCfgData* data, struct GasFieldData* fieldData,
933 struct Bme688GasRawData *gasRawData)
934 {
935 if (g_bme688State.variantId == BME68X_VARIANT_GAS_HIGH) {
936 fieldData->gas_resistance = BmeHalCalcGasResistanceHigh(gasRawData->adc_gas_res_high,
937 gasRawData->gas_range_h);
938 } else {
939 fieldData->gas_resistance = BmeHalCalcGasResistanceLow(data,
940 gasRawData->adc_gas_res_low,
941 gasRawData->gas_range_l);
942 }
943 }
944
BmeHalReadFieldData(struct SensorCfgData * data,uint8_t index,struct GasFieldData * fieldData)945 static int32_t BmeHalReadFieldData(struct SensorCfgData* data, uint8_t index,
946 struct GasFieldData* fieldData)
947 {
948 uint8_t buff[BME68X_LEN_FIELD] = {0};
949 uint32_t tries = BME688_TRY_TIMES;
950 uint32_t rc = HDF_SUCCESS;
951 struct Bme688GasRawData gasRaw;
952
953 CHECK_NULL_PTR_RETURN_VALUE(fieldData, HDF_ERR_INVALID_PARAM);
954
955 (void)memset_s(&gasRaw, sizeof(gasRaw), 0, sizeof(gasRaw));
956
957 while (tries && (rc == HDF_SUCCESS)) {
958 rc = BmeHalRegRead(data, BME68X_REG_FIELD0 + index * BME68X_LEN_FIELD_OFFSET, buff, BME68X_LEN_FIELD);
959 if (rc != HDF_SUCCESS) {
960 HDF_LOGE("%s: Read data failed", __func__);
961 break;
962 }
963
964 ParseSensorData(buff, fieldData, &gasRaw);
965
966 if (g_bme688State.variantId == BME68X_VARIANT_GAS_HIGH) {
967 UpdateFieldDataStatus(fieldData, buff[16]);
968 } else {
969 UpdateFieldDataStatus(fieldData, buff[14]);
970 }
971
972 if (!(fieldData->status & BME68X_NEW_DATA_MSK)) {
973 OsalMDelay(BME688_DELAY_10);
974 tries--;
975 continue;
976 }
977
978 rc = ReadAdditionalRegisters(data, fieldData);
979 if (rc != HDF_SUCCESS) {
980 HDF_LOGE("%s: Read additional failed", __func__);
981 break;
982 }
983
984 fieldData->temperature = BmeHalCalcTemperature(data, gasRaw.adc_temp);
985 fieldData->pressure = BmeHalCalcPressure(data, gasRaw.adc_pres);
986 fieldData->humidity = BmeHalCalcHumidity(data, gasRaw.adc_hum);
987 CalculateGasResistance(data, fieldData, &gasRaw);
988 break;
989 }
990
991 return rc;
992 }
993
Bme688GetData(struct SensorCfgData * data,struct GasFieldData * fieldData,uint8_t opMode)994 static int32_t Bme688GetData(struct SensorCfgData *data, struct GasFieldData *fieldData, uint8_t opMode)
995 {
996 int32_t ret;
997
998 CHECK_NULL_PTR_RETURN_VALUE(data, HDF_ERR_INVALID_PARAM);
999 CHECK_NULL_PTR_RETURN_VALUE(fieldData, HDF_ERR_INVALID_PARAM);
1000
1001 if (opMode == BME68X_FORCED_MODE) {
1002 ret = BmeHalReadFieldData(data, 0, fieldData);
1003 if (ret != HDF_SUCCESS) {
1004 HDF_LOGE("%s: bme688 read field data failed", __func__);
1005 return HDF_FAILURE;
1006 }
1007 } else {
1008 HDF_LOGE("%s: sensor status error.", __func__);
1009 return HDF_FAILURE;
1010 }
1011
1012 return ret;
1013 }
1014
InitBme688(struct SensorCfgData * data)1015 static int32_t InitBme688(struct SensorCfgData *data)
1016 {
1017 int32_t ret = HDF_SUCCESS;
1018
1019 CHECK_NULL_PTR_RETURN_VALUE(data, HDF_ERR_INVALID_PARAM);
1020 ret = SetSensorRegCfgArray(&data->busCfg, data->regCfgGroup[SENSOR_INIT_GROUP]);
1021 if (ret != HDF_SUCCESS) {
1022 HDF_LOGE("%s: bme688 sensor init config failed", __func__);
1023 return HDF_FAILURE;
1024 }
1025
1026 ret = Bme688ReadVariantId(data);
1027 if (ret != HDF_SUCCESS) {
1028 HDF_LOGE("%s: bme688 sensor read variant id failed", __func__);
1029 return HDF_FAILURE;
1030 }
1031
1032 g_bme688State.workState = BME688_WORK_MODE_SUSPEND;
1033 g_bme688State.inited = BME68X_DISABLE;
1034
1035 return ret;
1036 }
1037
DispatchBme688(struct HdfDeviceIoClient * client,int cmd,struct HdfSBuf * data,struct HdfSBuf * reply)1038 static int32_t DispatchBme688(struct HdfDeviceIoClient *client, int cmd, struct HdfSBuf *data, struct HdfSBuf *reply)
1039 {
1040 (void)client;
1041 (void)cmd;
1042 (void)data;
1043 (void)reply;
1044
1045 return HDF_SUCCESS;
1046 }
1047
Bme688BindDriver(struct HdfDeviceObject * device)1048 static int32_t Bme688BindDriver(struct HdfDeviceObject *device)
1049 {
1050 OsalUDelay(BME688_DELAY_50);
1051 CHECK_NULL_PTR_RETURN_VALUE(device, HDF_ERR_INVALID_PARAM);
1052
1053 struct Bme688DrvData *drvData = (struct Bme688DrvData *)OsalMemCalloc(sizeof(*drvData));
1054 if (drvData == NULL) {
1055 HDF_LOGE("%s: Malloc Bme688 drv data fail", __func__);
1056 return HDF_ERR_MALLOC_FAIL;
1057 }
1058
1059 drvData->ioService.Dispatch = DispatchBme688;
1060 drvData->device = device;
1061 device->service = &drvData->ioService;
1062 g_bme688DrvData = drvData;
1063
1064 return HDF_SUCCESS;
1065 }
1066
Bme688InitDriver(struct HdfDeviceObject * device)1067 static int32_t Bme688InitDriver(struct HdfDeviceObject *device)
1068 {
1069 int32_t ret;
1070 struct GasOpsCall ops;
1071 CHECK_NULL_PTR_RETURN_VALUE(device, HDF_ERR_INVALID_PARAM);
1072 struct Bme688DrvData *drvData = (struct Bme688DrvData *)device->service;
1073 CHECK_NULL_PTR_RETURN_VALUE(drvData, HDF_ERR_INVALID_PARAM);
1074 CHECK_NULL_PTR_RETURN_VALUE(device->property, HDF_ERR_INVALID_PARAM);
1075
1076 drvData->sensorCfg = GasCreateCfgData(device->property);
1077 if (drvData->sensorCfg == NULL || drvData->sensorCfg->root == NULL) {
1078 HDF_LOGD("%s: Creating gascfg failed because detection failed", __func__);
1079 return HDF_ERR_NOT_SUPPORT;
1080 }
1081
1082 ops.Init = NULL;
1083 ops.ReadData = ReadBme688Data;
1084 ret = GasRegisterChipOps(&ops);
1085 if (ret != HDF_SUCCESS) {
1086 HDF_LOGE("%s: Register bme688 gas failed", __func__);
1087 return HDF_FAILURE;
1088 }
1089
1090 ret = Bme688SoftReset(drvData->sensorCfg);
1091 if (ret != HDF_SUCCESS) {
1092 HDF_LOGE("%s: bme688 dump data failed!", __func__);
1093 return ret;
1094 }
1095
1096 // validate chip id
1097 ret = Bme688ValChipId(drvData->sensorCfg);
1098 if (ret != HDF_SUCCESS) {
1099 return ret;
1100 }
1101
1102 ret = Bme688GetCalibData(drvData->sensorCfg, &g_calibData);
1103 if (ret != HDF_SUCCESS) {
1104 HDF_LOGE("%s: get calibration data in init process failed", __func__);
1105 return HDF_FAILURE;
1106 }
1107
1108 ret = InitBme688(drvData->sensorCfg);
1109 if (ret != HDF_SUCCESS) {
1110 HDF_LOGE("%s: Init bme688 gas failed", __func__);
1111 return HDF_FAILURE;
1112 }
1113
1114 return HDF_SUCCESS;
1115 }
1116
Bme688ReleaseDriver(struct HdfDeviceObject * device)1117 static void Bme688ReleaseDriver(struct HdfDeviceObject *device)
1118 {
1119 CHECK_NULL_PTR_RETURN(device);
1120
1121 struct Bme688DrvData *drvData = (struct Bme688DrvData *)device->service;
1122 CHECK_NULL_PTR_RETURN(drvData);
1123
1124 if (drvData->sensorCfg != NULL) {
1125 GasReleaseCfgData(drvData->sensorCfg);
1126 drvData->sensorCfg = NULL;
1127 }
1128
1129 OsalMemFree(drvData);
1130 }
1131
1132 struct HdfDriverEntry g_gasBme688DevEntry = {
1133 .moduleVersion = 1,
1134 .moduleName = "HDF_SENSOR_GAS_BME688",
1135 .Bind = Bme688BindDriver,
1136 .Init = Bme688InitDriver,
1137 .Release = Bme688ReleaseDriver,
1138 };
1139
1140 HDF_INIT(g_gasBme688DevEntry);
1141
1142