• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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, &regv, 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, &regv, 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, &currentOpMode);
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