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, &regv, 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, &regv, 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, &currentOpMode);
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