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