1094332d3Sopenharmony_ci/**
2094332d3Sopenharmony_ci* Copyright (c) 2024 Bosch Sensortec GmbH. All rights reserved.
3094332d3Sopenharmony_ci*
4094332d3Sopenharmony_ci* gas_bme688_driver.c as part of the * /chipsets subdirectory
5094332d3Sopenharmony_ci* is dual licensed: you can use it either under the terms of
6094332d3Sopenharmony_ci* the GPL, or the BSD license, at your option.
7094332d3Sopenharmony_ci* See the LICENSE file in the root of this repository for complete details.
8094332d3Sopenharmony_ci*/
9094332d3Sopenharmony_ci
10094332d3Sopenharmony_ci#include "gas_bme688_driver.h"
11094332d3Sopenharmony_ci#include "osal_mem.h"
12094332d3Sopenharmony_ci#include "osal_time.h"
13094332d3Sopenharmony_ci#include "sensor_config_controller.h"
14094332d3Sopenharmony_ci#include "sensor_device_manager.h"
15094332d3Sopenharmony_ci#include "sensor_gas_driver.h"
16094332d3Sopenharmony_ci#include <securec.h>
17094332d3Sopenharmony_ci
18094332d3Sopenharmony_ci#define HDF_LOG_TAG hdf_sensor_gas
19094332d3Sopenharmony_ci
20094332d3Sopenharmony_ci/* This internal API is used to calculate the temperature in integer */
21094332d3Sopenharmony_cistatic int16_t BmeHalCalcTemperature(struct SensorCfgData *data, uint32_t tempAdc);
22094332d3Sopenharmony_ci
23094332d3Sopenharmony_ci/* This internal API is used to calculate the pressure value in integer */
24094332d3Sopenharmony_cistatic uint32_t BmeHalCalcPressure(struct SensorCfgData *data, uint32_t presAdc);
25094332d3Sopenharmony_ci
26094332d3Sopenharmony_ci/* This internal API is used to calculate the humidity value in integer */
27094332d3Sopenharmony_cistatic uint32_t BmeHalCalcHumidity(struct SensorCfgData *data, uint16_t humADC);
28094332d3Sopenharmony_ci
29094332d3Sopenharmony_ci/* This internal API is used to calculate the gas resistance high value in integer */
30094332d3Sopenharmony_cistatic uint32_t BmeHalCalcGasResistanceHigh(uint16_t gasResAdc, uint8_t gasRange);
31094332d3Sopenharmony_ci
32094332d3Sopenharmony_ci/* This internal API is used to calculate the gas resistance low value in integer */
33094332d3Sopenharmony_cistatic uint32_t BmeHalCalcGasResistanceLow(struct SensorCfgData *data,
34094332d3Sopenharmony_ci                                           uint16_t gasResAdc, uint8_t gasRange);
35094332d3Sopenharmony_ci
36094332d3Sopenharmony_ci/* This internal API is used to calculate the heater resistance value using integer */
37094332d3Sopenharmony_cistatic uint8_t BmeHalCalcResHeat(struct SensorCfgData *data, uint16_t temp);
38094332d3Sopenharmony_ci
39094332d3Sopenharmony_ci/* This internal API is used to set gas wait and resistance heat config using integer*/
40094332d3Sopenharmony_cistatic int32_t BmeHalSetConfig(struct SensorCfgData *data,
41094332d3Sopenharmony_ci                               struct bme688HeatrConf *conf, uint8_t opMode, uint8_t *nbConv);
42094332d3Sopenharmony_ci
43094332d3Sopenharmony_ci/* This internal API is used to calculate the gas wait */
44094332d3Sopenharmony_cistatic uint8_t BmeHalCalcGasWait(uint16_t dur);
45094332d3Sopenharmony_ci
46094332d3Sopenharmony_ci/* This internal API is used to read a single data of the sensor */
47094332d3Sopenharmony_cistatic int32_t BmeHalReadFieldData(struct SensorCfgData *data, uint8_t index,
48094332d3Sopenharmony_ci                                   struct GasFieldData *fieldData);
49094332d3Sopenharmony_ci
50094332d3Sopenharmony_ci/* This internal API is used to get operation mode */
51094332d3Sopenharmony_cistatic int32_t Bme688GetOpMode(struct SensorCfgData *data, uint8_t *opMode);
52094332d3Sopenharmony_ci
53094332d3Sopenharmony_ci/* This internal API is used to set operation mode */
54094332d3Sopenharmony_cistatic int32_t Bme688SetOpMode(struct SensorCfgData *data, const uint8_t opMode);
55094332d3Sopenharmony_ci
56094332d3Sopenharmony_ci/* This internal API is used to get measurement duration */
57094332d3Sopenharmony_cistatic uint32_t Bme688GetMeasDur(struct SensorCfgData *data, const uint8_t opMode,
58094332d3Sopenharmony_ci                                 struct GasCfg *gascfg);
59094332d3Sopenharmony_ci
60094332d3Sopenharmony_ci/* This internal API is used to set configuration */
61094332d3Sopenharmony_cistatic int32_t Bme688SetConfig(struct SensorCfgData *data, struct GasCfg *gascfg);
62094332d3Sopenharmony_ci
63094332d3Sopenharmony_ci/* This internal API is used to set heatr configuration */
64094332d3Sopenharmony_cistatic int32_t Bme688SetHeatrConfig(struct SensorCfgData *data, struct bme688HeatrConf *conf,
65094332d3Sopenharmony_ci                                    uint8_t opMode);
66094332d3Sopenharmony_ci
67094332d3Sopenharmony_ci/* This internal API is used to limit the max value of a parameter */
68094332d3Sopenharmony_cistatic int32_t BmeHalBoundaryCheck(struct SensorCfgData *data, uint8_t *value, uint8_t max);
69094332d3Sopenharmony_ci
70094332d3Sopenharmony_ci/* This internal API is used to read the sensor data */
71094332d3Sopenharmony_cistatic int32_t Bme688GetData(struct SensorCfgData *data, struct GasFieldData *fieldData,
72094332d3Sopenharmony_ci                             uint8_t opMode);
73094332d3Sopenharmony_ci
74094332d3Sopenharmony_cistatic struct Bme688DrvData *g_bme688DrvData = NULL;
75094332d3Sopenharmony_cistatic struct Bme688CalibData g_calibData;
76094332d3Sopenharmony_cistatic int16_t reTemp = 0;
77094332d3Sopenharmony_cistatic uint32_t reData[4] = {0};
78094332d3Sopenharmony_cistatic struct Bme688Status g_bme688State;
79094332d3Sopenharmony_ci
80094332d3Sopenharmony_cistatic struct Bme688DrvData *Bme688GetDrvData(void)
81094332d3Sopenharmony_ci{
82094332d3Sopenharmony_ci    return g_bme688DrvData;
83094332d3Sopenharmony_ci}
84094332d3Sopenharmony_ci
85094332d3Sopenharmony_ci/// @brief basic register write one byte function
86094332d3Sopenharmony_ci/// @param data       Sensor configuration data structre pointer
87094332d3Sopenharmony_ci/// @param rega       register address
88094332d3Sopenharmony_ci/// @param buffer     value to write
89094332d3Sopenharmony_ci/// @return           HDF_SUCCESS if success, failed any error
90094332d3Sopenharmony_cistatic int32_t BmeHalRegWriteOneByte(struct SensorCfgData *data, uint8_t rega, uint8_t buffer)
91094332d3Sopenharmony_ci{
92094332d3Sopenharmony_ci    int32_t rc = HDF_SUCCESS;
93094332d3Sopenharmony_ci    int32_t index = 0;
94094332d3Sopenharmony_ci    uint8_t g_regw_buffer[20];
95094332d3Sopenharmony_ci    uint8_t len = 1;
96094332d3Sopenharmony_ci    (void)memset_s(g_regw_buffer, sizeof(g_regw_buffer), 0, sizeof(g_regw_buffer));
97094332d3Sopenharmony_ci
98094332d3Sopenharmony_ci    CHECK_NULL_PTR_RETURN_VALUE(data, HDF_ERR_INVALID_PARAM);
99094332d3Sopenharmony_ci
100094332d3Sopenharmony_ci    g_regw_buffer[0] = (rega & 0xFF);
101094332d3Sopenharmony_ci    do {
102094332d3Sopenharmony_ci        g_regw_buffer[index + 1] = buffer;
103094332d3Sopenharmony_ci        index++;
104094332d3Sopenharmony_ci    } while (index < len);
105094332d3Sopenharmony_ci
106094332d3Sopenharmony_ci    rc = WriteSensor(&data->busCfg, g_regw_buffer, (len + 1));
107094332d3Sopenharmony_ci    OsalUDelay(BME688_DELAY_10);
108094332d3Sopenharmony_ci
109094332d3Sopenharmony_ci    if (rc != HDF_SUCCESS) {
110094332d3Sopenharmony_ci        HDF_LOGE("%s: [BME688] w reg:%d err", __func__, rega);
111094332d3Sopenharmony_ci    }
112094332d3Sopenharmony_ci
113094332d3Sopenharmony_ci    return rc;
114094332d3Sopenharmony_ci}
115094332d3Sopenharmony_ci
116094332d3Sopenharmony_ci/// @brief basic register write multiply byte function
117094332d3Sopenharmony_ci/// @param data       Sensor configuration data structre pointer
118094332d3Sopenharmony_ci/// @param rega       register address
119094332d3Sopenharmony_ci/// @param buffer     value to write
120094332d3Sopenharmony_ci/// @param len        write len
121094332d3Sopenharmony_ci/// @return           HDF_SUCCESS if success, failed any error
122094332d3Sopenharmony_cistatic int32_t BmeHalRegWriteMulByte(struct SensorCfgData *data, uint8_t *rega, uint8_t *buffer, uint32_t len)
123094332d3Sopenharmony_ci{
124094332d3Sopenharmony_ci    int32_t rc = HDF_SUCCESS;
125094332d3Sopenharmony_ci    int32_t index = 0;
126094332d3Sopenharmony_ci
127094332d3Sopenharmony_ci    CHECK_NULL_PTR_RETURN_VALUE(data, HDF_ERR_INVALID_PARAM);
128094332d3Sopenharmony_ci
129094332d3Sopenharmony_ci    do {
130094332d3Sopenharmony_ci        rc = BmeHalRegWriteOneByte(data, rega[index], buffer[index]);
131094332d3Sopenharmony_ci        index++;
132094332d3Sopenharmony_ci    } while (index < len);
133094332d3Sopenharmony_ci
134094332d3Sopenharmony_ci    return rc;
135094332d3Sopenharmony_ci}
136094332d3Sopenharmony_ci
137094332d3Sopenharmony_ci/// @brief basic register read function
138094332d3Sopenharmony_ci/// @param data      Sensor configuration data structre pointer
139094332d3Sopenharmony_ci/// @param rega      register address to read
140094332d3Sopenharmony_ci/// @param buffer    read data buffer
141094332d3Sopenharmony_ci/// @param len       read len
142094332d3Sopenharmony_ci/// @return          HDF_SUCCESS if success, failed any error
143094332d3Sopenharmony_cistatic int32_t BmeHalRegRead(struct SensorCfgData *data, uint16_t rega, uint8_t *buffer, uint32_t len)
144094332d3Sopenharmony_ci{
145094332d3Sopenharmony_ci    int32_t rc = HDF_SUCCESS;
146094332d3Sopenharmony_ci
147094332d3Sopenharmony_ci    rc = ReadSensor(&data->busCfg, rega, buffer, len);
148094332d3Sopenharmony_ci    if (rc != HDF_SUCCESS) {
149094332d3Sopenharmony_ci        HDF_LOGE("%s: [BME688] r reg:%d err", __func__, rega);
150094332d3Sopenharmony_ci    }
151094332d3Sopenharmony_ci    OsalUDelay(BME688_DELAY_4);
152094332d3Sopenharmony_ci
153094332d3Sopenharmony_ci    return rc;
154094332d3Sopenharmony_ci}
155094332d3Sopenharmony_ci
156094332d3Sopenharmony_cistatic int32_t Bme688HalReadSensorRawData(struct SensorCfgData *data, struct GasData *rawData)
157094332d3Sopenharmony_ci{
158094332d3Sopenharmony_ci    struct GasFieldData fieldData = { 0 };
159094332d3Sopenharmony_ci    uint8_t opMode = 0;
160094332d3Sopenharmony_ci    int32_t ret = HDF_SUCCESS;
161094332d3Sopenharmony_ci
162094332d3Sopenharmony_ci    ret = Bme688GetOpMode(data, &opMode);
163094332d3Sopenharmony_ci    if ((opMode & BME68X_MODE_MSK) == BME68X_SLEEP_MODE) {
164094332d3Sopenharmony_ci        ret = Bme688GetData(data, &fieldData, BME68X_FORCED_MODE);
165094332d3Sopenharmony_ci
166094332d3Sopenharmony_ci        g_bme688State.workState = BME688_WORK_MODE_SUSPEND;
167094332d3Sopenharmony_ci
168094332d3Sopenharmony_ci        rawData->gasResitance = fieldData.gas_resistance;
169094332d3Sopenharmony_ci        rawData->heatSource = BME688_HEATR_TEMP;
170094332d3Sopenharmony_ci        rawData->temperature = fieldData.temperature;
171094332d3Sopenharmony_ci        rawData->humidity = fieldData.humidity;
172094332d3Sopenharmony_ci        rawData->pressure = fieldData.pressure;
173094332d3Sopenharmony_ci
174094332d3Sopenharmony_ci        reData[RESISTANCE] = fieldData.gas_resistance;
175094332d3Sopenharmony_ci        reData[TEMPERATURE] = BME688_HEATR_TEMP;
176094332d3Sopenharmony_ci        reTemp = fieldData.temperature;
177094332d3Sopenharmony_ci        reData[HUMIDITY] = fieldData.humidity;
178094332d3Sopenharmony_ci        reData[PRESSURE] = fieldData.pressure;
179094332d3Sopenharmony_ci    } else if ((opMode & BME68X_MODE_MSK) == BME68X_FORCED_MODE) {
180094332d3Sopenharmony_ci        rawData->gasResitance = reData[RESISTANCE];
181094332d3Sopenharmony_ci        rawData->heatSource = reData[TEMPERATURE];
182094332d3Sopenharmony_ci        rawData->temperature = reTemp;
183094332d3Sopenharmony_ci        rawData->humidity = reData[HUMIDITY];
184094332d3Sopenharmony_ci        rawData->pressure = reData[PRESSURE];
185094332d3Sopenharmony_ci    } else {
186094332d3Sopenharmony_ci        HDF_LOGE("%s: opMode ERROR!", __func__);
187094332d3Sopenharmony_ci        return HDF_FAILURE;
188094332d3Sopenharmony_ci    }
189094332d3Sopenharmony_ci
190094332d3Sopenharmony_ci    return ret;
191094332d3Sopenharmony_ci}
192094332d3Sopenharmony_ci
193094332d3Sopenharmony_ci/// @brief basic register write function
194094332d3Sopenharmony_ci/// @param data       Sensor configuration data structre pointer
195094332d3Sopenharmony_ci/// @param rega       register address
196094332d3Sopenharmony_ci/// @param buffer     value to write
197094332d3Sopenharmony_ci/// @param len        write len
198094332d3Sopenharmony_ci/// @return           HDF_SUCCESS if success, failed any error
199094332d3Sopenharmony_cistatic int32_t ReadBme688RawData(struct SensorCfgData *data, struct GasData *rawData, int64_t *timestamp)
200094332d3Sopenharmony_ci{
201094332d3Sopenharmony_ci    OsalTimespec time;
202094332d3Sopenharmony_ci    uint8_t regv[GAS_PART_SUM] = {0};
203094332d3Sopenharmony_ci    int32_t ret = HDF_SUCCESS;
204094332d3Sopenharmony_ci    struct GasFieldData fieldData = { 0 };
205094332d3Sopenharmony_ci    struct GasCfg conf;
206094332d3Sopenharmony_ci    struct bme688HeatrConf heatConf;
207094332d3Sopenharmony_ci    (void)memset_s(&time, sizeof(time), 0, sizeof(time));
208094332d3Sopenharmony_ci    (void)memset_s(regv, sizeof(regv), 0, sizeof(regv));
209094332d3Sopenharmony_ci
210094332d3Sopenharmony_ci    CHECK_NULL_PTR_RETURN_VALUE(data, HDF_ERR_INVALID_PARAM);
211094332d3Sopenharmony_ci
212094332d3Sopenharmony_ci    if (OsalGetTime(&time) != HDF_SUCCESS) {
213094332d3Sopenharmony_ci        HDF_LOGE("%s: Get time failed", __func__);
214094332d3Sopenharmony_ci        return HDF_FAILURE;
215094332d3Sopenharmony_ci    }
216094332d3Sopenharmony_ci    *timestamp = time.sec * SENSOR_SECOND_CONVERT_NANOSECOND + time.usec * SENSOR_CONVERT_UNIT; /* unit nanosecond */
217094332d3Sopenharmony_ci
218094332d3Sopenharmony_ci    if (g_bme688State.workState == BME688_WORK_MODE_SUSPEND) {
219094332d3Sopenharmony_ci        if (g_bme688State.inited != BME68X_ENABLE) {
220094332d3Sopenharmony_ci            conf.humOs = BME68X_OS_16X;
221094332d3Sopenharmony_ci            conf.tempOs = BME68X_OS_2X;
222094332d3Sopenharmony_ci            conf.presOs = BME68X_OS_1X;
223094332d3Sopenharmony_ci            conf.filter = BME68X_FILTER_OFF;
224094332d3Sopenharmony_ci            conf.odr = BME68X_ODR_NONE;
225094332d3Sopenharmony_ci
226094332d3Sopenharmony_ci            ret = Bme688SetConfig(data, &conf);
227094332d3Sopenharmony_ci            if (ret != HDF_SUCCESS) {
228094332d3Sopenharmony_ci                HDF_LOGE("%s: bme688 sensor set oversample config failed", __func__);
229094332d3Sopenharmony_ci                return HDF_FAILURE;
230094332d3Sopenharmony_ci            }
231094332d3Sopenharmony_ci
232094332d3Sopenharmony_ci            heatConf.enable = BME68X_ENABLE;
233094332d3Sopenharmony_ci            heatConf.heatr_temp = BME688_HEATR_TEMP;
234094332d3Sopenharmony_ci            heatConf.heatr_dur = BME688_HEATR_DUR;
235094332d3Sopenharmony_ci
236094332d3Sopenharmony_ci            ret = Bme688SetHeatrConfig(data, &heatConf, BME68X_FORCED_MODE);
237094332d3Sopenharmony_ci            g_bme688State.inited = BME68X_ENABLE;
238094332d3Sopenharmony_ci        }
239094332d3Sopenharmony_ci
240094332d3Sopenharmony_ci        ret = Bme688SetOpMode(data, BME68X_FORCED_MODE);
241094332d3Sopenharmony_ci        g_bme688State.workState = BME688_WORK_MODE_IDLE;
242094332d3Sopenharmony_ci    }
243094332d3Sopenharmony_ci
244094332d3Sopenharmony_ci    if (g_bme688State.workState == BME688_WORK_MODE_IDLE) {
245094332d3Sopenharmony_ci        ret = Bme688HalReadSensorRawData(data, rawData);
246094332d3Sopenharmony_ci    }
247094332d3Sopenharmony_ci
248094332d3Sopenharmony_ci    return ret;
249094332d3Sopenharmony_ci}
250094332d3Sopenharmony_ci
251094332d3Sopenharmony_ci/* read bme688 sensor data */
252094332d3Sopenharmony_cistatic int32_t ReadBme688Data(struct SensorCfgData *cfg, struct SensorReportEvent *event)
253094332d3Sopenharmony_ci{
254094332d3Sopenharmony_ci    int32_t ret;
255094332d3Sopenharmony_ci    struct GasData rawData = {0};
256094332d3Sopenharmony_ci    static int16_t tmp[GAS_DEP_PART_SUM];
257094332d3Sopenharmony_ci
258094332d3Sopenharmony_ci    CHECK_NULL_PTR_RETURN_VALUE(cfg, HDF_ERR_INVALID_PARAM);
259094332d3Sopenharmony_ci    CHECK_NULL_PTR_RETURN_VALUE(event, HDF_ERR_INVALID_PARAM);
260094332d3Sopenharmony_ci
261094332d3Sopenharmony_ci    ret = ReadBme688RawData(cfg, &rawData, (int64_t *)&event->timestamp);
262094332d3Sopenharmony_ci    if (ret != HDF_SUCCESS) {
263094332d3Sopenharmony_ci        HDF_LOGE("%s: bme688 read raw data failed", __func__);
264094332d3Sopenharmony_ci        return HDF_FAILURE;
265094332d3Sopenharmony_ci    }
266094332d3Sopenharmony_ci    event->sensorId = SENSOR_TAG_GAS;
267094332d3Sopenharmony_ci    event->option = 0;
268094332d3Sopenharmony_ci    event->mode = SENSOR_WORK_MODE_REALTIME;
269094332d3Sopenharmony_ci
270094332d3Sopenharmony_ci    HDF_LOGI("%s rawData->gasResitance = %d", __func__, rawData.gasResitance);
271094332d3Sopenharmony_ci    HDF_LOGI("%s rawData->heatSource = %d", __func__, rawData.heatSource);
272094332d3Sopenharmony_ci    HDF_LOGI("%s rawData->temperature = %d", __func__, rawData.temperature);
273094332d3Sopenharmony_ci    HDF_LOGI("%s rawData->humidity = %d", __func__, rawData.humidity);
274094332d3Sopenharmony_ci    HDF_LOGI("%s rawData->pressure = %d", __func__, rawData.pressure);
275094332d3Sopenharmony_ci
276094332d3Sopenharmony_ci    tmp[GAS_PART_GASRES] = rawData.gasResitance;
277094332d3Sopenharmony_ci    tmp[GAS_PART_HEAT] = rawData.heatSource;
278094332d3Sopenharmony_ci    tmp[GAS_PART_TEMP] = rawData.temperature;
279094332d3Sopenharmony_ci    tmp[GAS_PART_HUMI] = rawData.humidity;
280094332d3Sopenharmony_ci    tmp[GAS_PART_PRE] = rawData.pressure;
281094332d3Sopenharmony_ci
282094332d3Sopenharmony_ci    event->dataLen = sizeof(tmp);
283094332d3Sopenharmony_ci    event->data = (uint8_t *)&tmp;
284094332d3Sopenharmony_ci
285094332d3Sopenharmony_ci    return ret;
286094332d3Sopenharmony_ci}
287094332d3Sopenharmony_ci
288094332d3Sopenharmony_ci/* This internal API is used to soft reset sensor */
289094332d3Sopenharmony_cistatic int32_t Bme688SoftReset(struct SensorCfgData *data)
290094332d3Sopenharmony_ci{
291094332d3Sopenharmony_ci    int32_t rc;
292094332d3Sopenharmony_ci    uint8_t regv = BME68X_SOFT_RESET_CMD;
293094332d3Sopenharmony_ci
294094332d3Sopenharmony_ci    CHECK_NULL_PTR_RETURN_VALUE(data, HDF_ERR_INVALID_PARAM);
295094332d3Sopenharmony_ci
296094332d3Sopenharmony_ci    rc = BmeHalRegWriteOneByte(data, BME68X_REG_SOFT_RESET, regv);
297094332d3Sopenharmony_ci    if (rc != HDF_SUCCESS) {
298094332d3Sopenharmony_ci        HDF_LOGE("%s: bme688 write command register failed", __func__);
299094332d3Sopenharmony_ci        return HDF_FAILURE;
300094332d3Sopenharmony_ci    }
301094332d3Sopenharmony_ci    // delay 5ms after reset
302094332d3Sopenharmony_ci    OsalMDelay(BME688_DELAY_5);
303094332d3Sopenharmony_ci
304094332d3Sopenharmony_ci    return rc;
305094332d3Sopenharmony_ci}
306094332d3Sopenharmony_ci
307094332d3Sopenharmony_ci/* This internal API is used to validate chip id */
308094332d3Sopenharmony_cistatic int32_t Bme688ValChipId(struct SensorCfgData *data)
309094332d3Sopenharmony_ci{
310094332d3Sopenharmony_ci    uint8_t regv = 0;
311094332d3Sopenharmony_ci    int32_t rc = HDF_SUCCESS;
312094332d3Sopenharmony_ci
313094332d3Sopenharmony_ci    rc = BmeHalRegRead(data, BME68X_REG_CHIP_ID, &regv, 1);
314094332d3Sopenharmony_ci    if (rc != HDF_SUCCESS) {
315094332d3Sopenharmony_ci        HDF_LOGE("%s: [BME688] WARN!!, NO Sensor", __func__);
316094332d3Sopenharmony_ci        return HDF_FAILURE;
317094332d3Sopenharmony_ci    }
318094332d3Sopenharmony_ci
319094332d3Sopenharmony_ci    HDF_LOGI("%s: rc = %d, WHO_AMI: 0x%x", __func__, rc, regv);
320094332d3Sopenharmony_ci
321094332d3Sopenharmony_ci    if (regv != BME68X_CHIP_ID) {
322094332d3Sopenharmony_ci        rc = HDF_DEV_ERR_NO_DEVICE;
323094332d3Sopenharmony_ci    }
324094332d3Sopenharmony_ci
325094332d3Sopenharmony_ci    return rc;
326094332d3Sopenharmony_ci}
327094332d3Sopenharmony_ci
328094332d3Sopenharmony_ci/* This internal API is used to read variant id */
329094332d3Sopenharmony_cistatic int32_t Bme688ReadVariantId(struct SensorCfgData *data)
330094332d3Sopenharmony_ci{
331094332d3Sopenharmony_ci    uint8_t regv = 0;
332094332d3Sopenharmony_ci    int32_t rc = HDF_SUCCESS;
333094332d3Sopenharmony_ci
334094332d3Sopenharmony_ci    rc = BmeHalRegRead(data, BME68X_REG_VARIANT_ID, &regv, 1);
335094332d3Sopenharmony_ci    if (rc != HDF_SUCCESS) {
336094332d3Sopenharmony_ci        HDF_LOGE("%s: [BME688] read variant id failed", __func__);
337094332d3Sopenharmony_ci        return HDF_FAILURE;
338094332d3Sopenharmony_ci    }
339094332d3Sopenharmony_ci    HDF_LOGI("%s: rc = %d, regv = 0x%x", __func__, rc, regv);
340094332d3Sopenharmony_ci    g_bme688State.variantId = regv;
341094332d3Sopenharmony_ci    return rc;
342094332d3Sopenharmony_ci}
343094332d3Sopenharmony_ci
344094332d3Sopenharmony_ci/* function calculate the coeff from register to local before sensor data calibration */
345094332d3Sopenharmony_cistatic void Bme688GetCofParam(struct Bme688CalibData *myCalibData, uint8_t* coeff_array)
346094332d3Sopenharmony_ci{
347094332d3Sopenharmony_ci    /* Temperature related coefficients */
348094332d3Sopenharmony_ci    myCalibData->par_t1 =
349094332d3Sopenharmony_ci        (uint16_t)(BME68X_CONCAT_BYTES(coeff_array[BME68X_IDX_T1_MSB], coeff_array[BME68X_IDX_T1_LSB]));
350094332d3Sopenharmony_ci    myCalibData->par_t2 =
351094332d3Sopenharmony_ci        (int16_t)(BME68X_CONCAT_BYTES(coeff_array[BME68X_IDX_T2_MSB], coeff_array[BME68X_IDX_T2_LSB]));
352094332d3Sopenharmony_ci    myCalibData->par_t3 =
353094332d3Sopenharmony_ci        (int8_t)(coeff_array[BME68X_IDX_T3]);
354094332d3Sopenharmony_ci
355094332d3Sopenharmony_ci    /* Pressure related coefficients */
356094332d3Sopenharmony_ci    myCalibData->par_p1 =
357094332d3Sopenharmony_ci        (uint16_t)(BME68X_CONCAT_BYTES(coeff_array[BME68X_IDX_P1_MSB], coeff_array[BME68X_IDX_P1_LSB]));
358094332d3Sopenharmony_ci    myCalibData->par_p2 =
359094332d3Sopenharmony_ci        (int16_t)(BME68X_CONCAT_BYTES(coeff_array[BME68X_IDX_P2_MSB], coeff_array[BME68X_IDX_P2_LSB]));
360094332d3Sopenharmony_ci    myCalibData->par_p3 = (int8_t)coeff_array[BME68X_IDX_P3];
361094332d3Sopenharmony_ci    myCalibData->par_p4 =
362094332d3Sopenharmony_ci        (int16_t)(BME68X_CONCAT_BYTES(coeff_array[BME68X_IDX_P4_MSB], coeff_array[BME68X_IDX_P4_LSB]));
363094332d3Sopenharmony_ci    myCalibData->par_p5 =
364094332d3Sopenharmony_ci        (int16_t)(BME68X_CONCAT_BYTES(coeff_array[BME68X_IDX_P5_MSB], coeff_array[BME68X_IDX_P5_LSB]));
365094332d3Sopenharmony_ci    myCalibData->par_p6 = (int8_t)(coeff_array[BME68X_IDX_P6]);
366094332d3Sopenharmony_ci    myCalibData->par_p7 = (int8_t)(coeff_array[BME68X_IDX_P7]);
367094332d3Sopenharmony_ci    myCalibData->par_p8 =
368094332d3Sopenharmony_ci        (int16_t)(BME68X_CONCAT_BYTES(coeff_array[BME68X_IDX_P8_MSB], coeff_array[BME68X_IDX_P8_LSB]));
369094332d3Sopenharmony_ci    myCalibData->par_p9 =
370094332d3Sopenharmony_ci        (int16_t)(BME68X_CONCAT_BYTES(coeff_array[BME68X_IDX_P9_MSB], coeff_array[BME68X_IDX_P9_LSB]));
371094332d3Sopenharmony_ci    myCalibData->par_p10 = (uint8_t)(coeff_array[BME68X_IDX_P10]);
372094332d3Sopenharmony_ci
373094332d3Sopenharmony_ci     /* Humidity related coefficients */
374094332d3Sopenharmony_ci    myCalibData->par_h1 =
375094332d3Sopenharmony_ci        (uint16_t)(((uint16_t)coeff_array[BME68X_IDX_H1_MSB] << 4) |
376094332d3Sopenharmony_ci                    (coeff_array[BME68X_IDX_H1_LSB] & BME68X_BIT_H1_DATA_MSK));
377094332d3Sopenharmony_ci    myCalibData->par_h2 =
378094332d3Sopenharmony_ci        (uint16_t)(((uint16_t)coeff_array[BME68X_IDX_H2_MSB] << 4) | ((coeff_array[BME68X_IDX_H2_LSB]) >> 4));
379094332d3Sopenharmony_ci    myCalibData->par_h3 = (int8_t)coeff_array[BME68X_IDX_H3];
380094332d3Sopenharmony_ci    myCalibData->par_h4 = (int8_t)coeff_array[BME68X_IDX_H4];
381094332d3Sopenharmony_ci    myCalibData->par_h5 = (int8_t)coeff_array[BME68X_IDX_H5];
382094332d3Sopenharmony_ci    myCalibData->par_h6 = (uint8_t)coeff_array[BME68X_IDX_H6];
383094332d3Sopenharmony_ci    myCalibData->par_h7 = (int8_t)coeff_array[BME68X_IDX_H7];
384094332d3Sopenharmony_ci
385094332d3Sopenharmony_ci    /* Gas heater related coefficients */
386094332d3Sopenharmony_ci    myCalibData->par_gh1 = (int8_t)coeff_array[BME68X_IDX_GH1];
387094332d3Sopenharmony_ci    myCalibData->par_gh2 =
388094332d3Sopenharmony_ci        (int16_t)(BME68X_CONCAT_BYTES(coeff_array[BME68X_IDX_GH2_MSB], coeff_array[BME68X_IDX_GH2_LSB]));
389094332d3Sopenharmony_ci    myCalibData->par_gh3 = (int8_t)coeff_array[BME68X_IDX_GH3];
390094332d3Sopenharmony_ci
391094332d3Sopenharmony_ci    /* Other coefficients */
392094332d3Sopenharmony_ci    myCalibData->res_heat_range = ((coeff_array[BME68X_IDX_RES_HEAT_RANGE] & BME68X_RHRANGE_MSK) / 16);
393094332d3Sopenharmony_ci    myCalibData->res_heat_val = (int8_t)coeff_array[BME68X_IDX_RES_HEAT_VAL];
394094332d3Sopenharmony_ci    myCalibData->range_sw_err = ((int8_t)(coeff_array[BME68X_IDX_RANGE_SW_ERR] & BME68X_RSERROR_MSK)) / 16;
395094332d3Sopenharmony_ci}
396094332d3Sopenharmony_ci
397094332d3Sopenharmony_ci/* This internal API is used to get calibration data */
398094332d3Sopenharmony_cistatic int32_t Bme688GetCalibData(struct SensorCfgData *data,
399094332d3Sopenharmony_ci                                  struct Bme688CalibData *calibData)
400094332d3Sopenharmony_ci{
401094332d3Sopenharmony_ci    int32_t rc = HDF_SUCCESS;
402094332d3Sopenharmony_ci    uint8_t coeff_array[BME68X_LEN_COEFF_ALL] = {0};
403094332d3Sopenharmony_ci
404094332d3Sopenharmony_ci    rc = BmeHalRegRead(data, BME68X_REG_COEFF1, coeff_array, BME68X_LEN_COEFF1);
405094332d3Sopenharmony_ci    if (rc != HDF_SUCCESS) {
406094332d3Sopenharmony_ci        HDF_LOGE("%s: [BME688] read data from BME68X_REG_COEFF1 failed", __func__);
407094332d3Sopenharmony_ci        return HDF_FAILURE;
408094332d3Sopenharmony_ci    }
409094332d3Sopenharmony_ci
410094332d3Sopenharmony_ci    rc = BmeHalRegRead(data, BME68X_REG_COEFF2, &coeff_array[BME68X_LEN_COEFF1], BME68X_LEN_COEFF2);
411094332d3Sopenharmony_ci    if (rc != HDF_SUCCESS) {
412094332d3Sopenharmony_ci        HDF_LOGE("%s: [BME688] read data from BME68X_REG_COEFF2 failed", __func__);
413094332d3Sopenharmony_ci        return HDF_FAILURE;
414094332d3Sopenharmony_ci    }
415094332d3Sopenharmony_ci
416094332d3Sopenharmony_ci    rc = BmeHalRegRead(data, BME68X_REG_COEFF3, &coeff_array[BME68X_LEN_COEFF1 + BME68X_LEN_COEFF2], BME68X_LEN_COEFF3);
417094332d3Sopenharmony_ci    if (rc != HDF_SUCCESS) {
418094332d3Sopenharmony_ci        HDF_LOGE("%s: [BME688] read data from BME68X_REG_COEFF3 failed", __func__);
419094332d3Sopenharmony_ci        return HDF_FAILURE;
420094332d3Sopenharmony_ci    }
421094332d3Sopenharmony_ci
422094332d3Sopenharmony_ci    Bme688GetCofParam(calibData, coeff_array);
423094332d3Sopenharmony_ci
424094332d3Sopenharmony_ci    return rc;
425094332d3Sopenharmony_ci}
426094332d3Sopenharmony_ci
427094332d3Sopenharmony_cistatic int32_t Bme688GetOpMode(struct SensorCfgData *data, uint8_t *opMode)
428094332d3Sopenharmony_ci{
429094332d3Sopenharmony_ci    int32_t rc = HDF_SUCCESS;
430094332d3Sopenharmony_ci    uint8_t mode;
431094332d3Sopenharmony_ci
432094332d3Sopenharmony_ci    CHECK_NULL_PTR_RETURN_VALUE(opMode, HDF_ERR_INVALID_PARAM);
433094332d3Sopenharmony_ci
434094332d3Sopenharmony_ci    rc = BmeHalRegRead(data, BME68X_REG_CTRL_MEAS, &mode, 1);
435094332d3Sopenharmony_ci    *opMode = mode & BME68X_MODE_MSK;
436094332d3Sopenharmony_ci
437094332d3Sopenharmony_ci    return rc;
438094332d3Sopenharmony_ci}
439094332d3Sopenharmony_ci
440094332d3Sopenharmony_cistatic int32_t Bme688SetOpMode(struct SensorCfgData *data, const uint8_t opMode)
441094332d3Sopenharmony_ci{
442094332d3Sopenharmony_ci    int32_t rc;
443094332d3Sopenharmony_ci    uint8_t tmpPowMode;
444094332d3Sopenharmony_ci    uint8_t powMode = 0;
445094332d3Sopenharmony_ci    uint8_t regAddr = BME68X_REG_CTRL_MEAS;
446094332d3Sopenharmony_ci
447094332d3Sopenharmony_ci    do {
448094332d3Sopenharmony_ci        rc = BmeHalRegRead(data, regAddr, &tmpPowMode, 1);
449094332d3Sopenharmony_ci        if (rc != HDF_SUCCESS) {
450094332d3Sopenharmony_ci            HDF_LOGE("%s: [BME688] get power mode failed", __func__);
451094332d3Sopenharmony_ci        }
452094332d3Sopenharmony_ci        powMode = tmpPowMode & BME68X_MODE_MSK;
453094332d3Sopenharmony_ci        if (powMode != BME68X_SLEEP_MODE) {
454094332d3Sopenharmony_ci            tmpPowMode &= ~BME68X_MODE_MSK;
455094332d3Sopenharmony_ci            rc = BmeHalRegWriteOneByte(data, regAddr, tmpPowMode);
456094332d3Sopenharmony_ci            OsalMDelay(BME688_DELAY_10);
457094332d3Sopenharmony_ci        }
458094332d3Sopenharmony_ci    } while (powMode != BME68X_SLEEP_MODE && rc == HDF_SUCCESS);
459094332d3Sopenharmony_ci
460094332d3Sopenharmony_ci    if (opMode != BME68X_SLEEP_MODE && rc == HDF_SUCCESS) {
461094332d3Sopenharmony_ci        tmpPowMode = (tmpPowMode & ~BME68X_MODE_MSK) | (opMode & BME68X_MODE_MSK);
462094332d3Sopenharmony_ci        rc = BmeHalRegWriteOneByte(data, regAddr, tmpPowMode);
463094332d3Sopenharmony_ci    }
464094332d3Sopenharmony_ci
465094332d3Sopenharmony_ci    return rc;
466094332d3Sopenharmony_ci}
467094332d3Sopenharmony_ci
468094332d3Sopenharmony_cistatic int16_t BmeHalCalcTemperature(struct SensorCfgData *data, uint32_t tempAdc)
469094332d3Sopenharmony_ci{
470094332d3Sopenharmony_ci    int64_t var1;
471094332d3Sopenharmony_ci    int64_t var2;
472094332d3Sopenharmony_ci    int64_t var3;
473094332d3Sopenharmony_ci    int16_t calcTemp;
474094332d3Sopenharmony_ci
475094332d3Sopenharmony_ci    var1 = ((int32_t)tempAdc >> 3) - ((int32_t)g_calibData.par_t1 << 1);
476094332d3Sopenharmony_ci    var2 = (var1 * (int32_t)g_calibData.par_t2) >> 11;
477094332d3Sopenharmony_ci    var3 = ((var1 >> 1) * (var1 >> 1)) >> 12;
478094332d3Sopenharmony_ci    var3 = ((var3) * ((int32_t)g_calibData.par_t3 << 4)) >> 14;
479094332d3Sopenharmony_ci    g_calibData.t_fine = (int32_t)(var2 + var3);
480094332d3Sopenharmony_ci    calcTemp = (int16_t)(((g_calibData.t_fine * 5) + 128) >> 8);
481094332d3Sopenharmony_ci
482094332d3Sopenharmony_ci    /*measurement unit : degrees centigrade*/
483094332d3Sopenharmony_ci    return calcTemp / 100;
484094332d3Sopenharmony_ci}
485094332d3Sopenharmony_ci
486094332d3Sopenharmony_cistatic uint32_t BmeHalCalcPressure(struct SensorCfgData *data, uint32_t presAdc)
487094332d3Sopenharmony_ci{
488094332d3Sopenharmony_ci    int32_t var1;
489094332d3Sopenharmony_ci    int32_t var2;
490094332d3Sopenharmony_ci    int32_t var3;
491094332d3Sopenharmony_ci    int32_t pressureComp;
492094332d3Sopenharmony_ci
493094332d3Sopenharmony_ci    const int32_t pres_ovf_check = BME_INT32_C(0x40000000);
494094332d3Sopenharmony_ci
495094332d3Sopenharmony_ci    /*lint -save -e701 -e702 -e713 */
496094332d3Sopenharmony_ci    var1 = (((int32_t)g_calibData.t_fine) >> 1) - 64000;
497094332d3Sopenharmony_ci    var2 = ((((var1 >> 2) * (var1 >> 2)) >> 11) * (int32_t)g_calibData.par_p6) >> 2;
498094332d3Sopenharmony_ci    var2 = var2 + ((var1 * (int32_t)g_calibData.par_p5) << 1);
499094332d3Sopenharmony_ci    var2 = (var2 >> 2) + ((int32_t)g_calibData.par_p4 << 16);
500094332d3Sopenharmony_ci    var1 = (((((var1 >> 2) * (var1 >> 2)) >> 13) * ((int32_t)g_calibData.par_p3 << 5)) >> 3) +
501094332d3Sopenharmony_ci           (((int32_t)g_calibData.par_p2 * var1) >> 1);
502094332d3Sopenharmony_ci    var1 = var1 >> 18;
503094332d3Sopenharmony_ci    var1 = ((32768 + var1) * (int32_t)g_calibData.par_p1) >> 15;
504094332d3Sopenharmony_ci    pressureComp = 1048576 - presAdc;
505094332d3Sopenharmony_ci    pressureComp = (int32_t)((pressureComp - (var2 >> 12)) * ((uint32_t)3125));
506094332d3Sopenharmony_ci    if (pressureComp >= pres_ovf_check) {
507094332d3Sopenharmony_ci        pressureComp = ((pressureComp / var1) << 1);
508094332d3Sopenharmony_ci    } else {
509094332d3Sopenharmony_ci        pressureComp = ((pressureComp << 1) / var1);
510094332d3Sopenharmony_ci    }
511094332d3Sopenharmony_ci
512094332d3Sopenharmony_ci    var1 = ((int32_t)g_calibData.par_p9 * (int32_t)(((pressureComp >> 3) * (pressureComp >> 3)) >> 13)) >> 12;
513094332d3Sopenharmony_ci    var2 = ((int32_t)(pressureComp >> 2) * (int32_t)g_calibData.par_p8) >> 13;
514094332d3Sopenharmony_ci    var3 = ((int32_t)(pressureComp >> 8) * (int32_t)(pressureComp >> 8) * (int32_t)(pressureComp >> 8) *
515094332d3Sopenharmony_ci            (int32_t)g_calibData.par_p10) >> 17;
516094332d3Sopenharmony_ci    pressureComp = (int32_t)(pressureComp) + ((var1 + var2 + var3 + ((int32_t)g_calibData.par_p7 << 7)) >> 4);
517094332d3Sopenharmony_ci
518094332d3Sopenharmony_ci    /*lint -restore */
519094332d3Sopenharmony_ci    /*measurement unit : kPa*/
520094332d3Sopenharmony_ci    return (uint32_t)pressureComp / 100;
521094332d3Sopenharmony_ci}
522094332d3Sopenharmony_ci
523094332d3Sopenharmony_cistatic uint32_t BmeHalCalcHumidity(struct SensorCfgData *data, uint16_t humADC)
524094332d3Sopenharmony_ci{
525094332d3Sopenharmony_ci    int32_t var1;
526094332d3Sopenharmony_ci    int32_t var2;
527094332d3Sopenharmony_ci    int32_t var3;
528094332d3Sopenharmony_ci    int32_t var4;
529094332d3Sopenharmony_ci    int32_t var5;
530094332d3Sopenharmony_ci    int32_t var6;
531094332d3Sopenharmony_ci    int32_t tempScaled;
532094332d3Sopenharmony_ci    int32_t calcHum;
533094332d3Sopenharmony_ci
534094332d3Sopenharmony_ci    /*lint -save -e702 -e704 */
535094332d3Sopenharmony_ci    tempScaled = (((int32_t)g_calibData.t_fine * 5) + 128) >> 8;
536094332d3Sopenharmony_ci    var1 = (int32_t)(humADC - ((int32_t)((int32_t)g_calibData.par_h1 * 16))) -
537094332d3Sopenharmony_ci           (((tempScaled * (int32_t)g_calibData.par_h3) / ((int32_t)100)) >> 1);
538094332d3Sopenharmony_ci    var2 =
539094332d3Sopenharmony_ci        ((int32_t)g_calibData.par_h2 *
540094332d3Sopenharmony_ci        (((tempScaled * (int32_t)g_calibData.par_h4) / ((int32_t)100)) +
541094332d3Sopenharmony_ci        (((tempScaled * ((tempScaled * (int32_t)g_calibData.par_h5) / ((int32_t)100))) >> 6) / ((int32_t)100)) +
542094332d3Sopenharmony_ci        (int32_t)(1 << 14))) >> 10;
543094332d3Sopenharmony_ci    var3 = var1 * var2;
544094332d3Sopenharmony_ci    var4 = (int32_t)g_calibData.par_h6 << 7;
545094332d3Sopenharmony_ci    var4 = ((var4) + ((tempScaled * (int32_t)g_calibData.par_h7) / ((int32_t)100))) >> 4;
546094332d3Sopenharmony_ci    var5 = ((var3 >> 14) * (var3 >> 14)) >> 10;
547094332d3Sopenharmony_ci    var6 = (var4 * var5) >> 1;
548094332d3Sopenharmony_ci
549094332d3Sopenharmony_ci    calcHum = (((var3 + var6) >> 10) * ((int32_t)1000)) >> 12;
550094332d3Sopenharmony_ci
551094332d3Sopenharmony_ci    /* Cap at 100%rH */
552094332d3Sopenharmony_ci    if (calcHum > BME688_MAX_HUM) {
553094332d3Sopenharmony_ci        calcHum = BME688_MAX_HUM;
554094332d3Sopenharmony_ci    } else if (calcHum < 0) {
555094332d3Sopenharmony_ci        calcHum = 0;
556094332d3Sopenharmony_ci    }
557094332d3Sopenharmony_ci
558094332d3Sopenharmony_ci    /*lint -restore */
559094332d3Sopenharmony_ci    /*measurement unit : Integer*/
560094332d3Sopenharmony_ci    return (uint32_t)calcHum / 1000;
561094332d3Sopenharmony_ci}
562094332d3Sopenharmony_ci
563094332d3Sopenharmony_cistatic uint32_t BmeHalCalcGasResistanceHigh(uint16_t gasResAdc, uint8_t gasRange)
564094332d3Sopenharmony_ci{
565094332d3Sopenharmony_ci    uint32_t calc_gas_res;
566094332d3Sopenharmony_ci    uint32_t var1 = BME_UINT32_C(262144) >> gasRange;
567094332d3Sopenharmony_ci    int32_t var2 = (int32_t)gasResAdc - BME_INT32_C(512);
568094332d3Sopenharmony_ci
569094332d3Sopenharmony_ci    var2 *= BME_INT32_C(3);
570094332d3Sopenharmony_ci    var2 = BME_INT32_C(4096) + var2;
571094332d3Sopenharmony_ci
572094332d3Sopenharmony_ci    /* multiplying 10000 then dividing then multiplying by 100 instead of multiplying by 1000000 to prevent overflow */
573094332d3Sopenharmony_ci    calc_gas_res = (BME_UINT32_C(10000) * var1) / (uint32_t)var2;
574094332d3Sopenharmony_ci    calc_gas_res = calc_gas_res * 100;
575094332d3Sopenharmony_ci
576094332d3Sopenharmony_ci    return calc_gas_res;
577094332d3Sopenharmony_ci}
578094332d3Sopenharmony_ci
579094332d3Sopenharmony_cistatic uint32_t BmeHalCalcGasResistanceLow(struct SensorCfgData *data,
580094332d3Sopenharmony_ci                                           uint16_t gasResAdc, uint8_t gasRange)
581094332d3Sopenharmony_ci{
582094332d3Sopenharmony_ci    int64_t var1;
583094332d3Sopenharmony_ci    uint64_t var2;
584094332d3Sopenharmony_ci    int64_t var3;
585094332d3Sopenharmony_ci    uint32_t calc_gas_res;
586094332d3Sopenharmony_ci    uint32_t lookup_table1[16] = {
587094332d3Sopenharmony_ci        BME_UINT32_C(2147483647), BME_UINT32_C(2147483647), BME_UINT32_C(2147483647),
588094332d3Sopenharmony_ci        BME_UINT32_C(2147483647), BME_UINT32_C(2147483647), BME_UINT32_C(2126008810),
589094332d3Sopenharmony_ci        BME_UINT32_C(2147483647), BME_UINT32_C(2130303777), BME_UINT32_C(2147483647),
590094332d3Sopenharmony_ci        BME_UINT32_C(2147483647), BME_UINT32_C(2143188679), BME_UINT32_C(2136746228),
591094332d3Sopenharmony_ci        BME_UINT32_C(2147483647), BME_UINT32_C(2126008810), BME_UINT32_C(2147483647),
592094332d3Sopenharmony_ci        BME_UINT32_C(2147483647)
593094332d3Sopenharmony_ci    };
594094332d3Sopenharmony_ci    uint32_t lookup_table2[16] = {
595094332d3Sopenharmony_ci        BME_UINT32_C(4096000000), BME_UINT32_C(2048000000), BME_UINT32_C(1024000000),
596094332d3Sopenharmony_ci        BME_UINT32_C(512000000), BME_UINT32_C(255744255), BME_UINT32_C(127110228),
597094332d3Sopenharmony_ci        BME_UINT32_C(64000000), BME_UINT32_C(32258064), BME_UINT32_C(16016016),
598094332d3Sopenharmony_ci        BME_UINT32_C(8000000), BME_UINT32_C(4000000), BME_UINT32_C(2000000),
599094332d3Sopenharmony_ci        BME_UINT32_C(1000000), BME_UINT32_C(500000), BME_UINT32_C(250000),
600094332d3Sopenharmony_ci        BME_UINT32_C(125000)
601094332d3Sopenharmony_ci    };
602094332d3Sopenharmony_ci
603094332d3Sopenharmony_ci    /*lint -save -e704 */
604094332d3Sopenharmony_ci    var1 = (int64_t)((1340 +
605094332d3Sopenharmony_ci             (5 * (int64_t)g_calibData.range_sw_err)) * ((int64_t)lookup_table1[gasRange])) >> 16;
606094332d3Sopenharmony_ci    var2 = (((int64_t)((int64_t)gasResAdc << 15) - (int64_t)(16777216)) + var1);
607094332d3Sopenharmony_ci    var3 = (((int64_t)lookup_table2[gasRange] * (int64_t)var1) >> 9);
608094332d3Sopenharmony_ci    calc_gas_res = (uint32_t)((var3 + ((int64_t)var2 >> 1)) / (int64_t)var2);
609094332d3Sopenharmony_ci
610094332d3Sopenharmony_ci    /*lint -restore */
611094332d3Sopenharmony_ci    return calc_gas_res;
612094332d3Sopenharmony_ci}
613094332d3Sopenharmony_ci
614094332d3Sopenharmony_cistatic uint8_t BmeHalCalcResHeat(struct SensorCfgData *data, uint16_t temp)
615094332d3Sopenharmony_ci{
616094332d3Sopenharmony_ci    uint8_t heatr_res;
617094332d3Sopenharmony_ci    int32_t var1;
618094332d3Sopenharmony_ci    int32_t var2;
619094332d3Sopenharmony_ci    int32_t var3;
620094332d3Sopenharmony_ci    int32_t var4;
621094332d3Sopenharmony_ci    int32_t var5;
622094332d3Sopenharmony_ci    int32_t heatr_res_x100;
623094332d3Sopenharmony_ci
624094332d3Sopenharmony_ci    /* Cap temperature */
625094332d3Sopenharmony_ci    if (temp > BME688_MAX_TEMP) {
626094332d3Sopenharmony_ci        temp = BME688_MAX_TEMP;
627094332d3Sopenharmony_ci    }
628094332d3Sopenharmony_ci
629094332d3Sopenharmony_ci    var1 = (((int32_t)BME688_AMB_TEMP * g_calibData.par_gh3) / 1000) * 256;
630094332d3Sopenharmony_ci    var2 = (g_calibData.par_gh1 + 784) *
631094332d3Sopenharmony_ci                (((((g_calibData.par_gh2 + 154009) * temp * 5) / 100) + 3276800) / 10);
632094332d3Sopenharmony_ci    var3 = var1 + (var2 / 2);
633094332d3Sopenharmony_ci    var4 = (var3 / (g_calibData.res_heat_range + 4));
634094332d3Sopenharmony_ci    var5 = (131 * g_calibData.res_heat_val) + 65536;
635094332d3Sopenharmony_ci    heatr_res_x100 = (int32_t)(((var4 / var5) - 250) * 34);
636094332d3Sopenharmony_ci    heatr_res = (uint8_t)((heatr_res_x100 + 50) / 100);
637094332d3Sopenharmony_ci
638094332d3Sopenharmony_ci    return heatr_res;
639094332d3Sopenharmony_ci}
640094332d3Sopenharmony_ci
641094332d3Sopenharmony_cistatic uint8_t BmeHalCalcGasWait(uint16_t dur)
642094332d3Sopenharmony_ci{
643094332d3Sopenharmony_ci    uint8_t factor = 0;
644094332d3Sopenharmony_ci    uint8_t durVal;
645094332d3Sopenharmony_ci
646094332d3Sopenharmony_ci    if (dur > 0xfc0) {
647094332d3Sopenharmony_ci        durVal = 0xff;
648094332d3Sopenharmony_ci    } else {
649094332d3Sopenharmony_ci        while (dur > 0x3f) {
650094332d3Sopenharmony_ci            dur /= 4;
651094332d3Sopenharmony_ci            factor++;
652094332d3Sopenharmony_ci        }
653094332d3Sopenharmony_ci        durVal = (uint8_t)(dur + (factor * 64));
654094332d3Sopenharmony_ci    }
655094332d3Sopenharmony_ci
656094332d3Sopenharmony_ci    return durVal;
657094332d3Sopenharmony_ci}
658094332d3Sopenharmony_ci
659094332d3Sopenharmony_cistatic uint32_t Bme688GetMeasDur(struct SensorCfgData *data, const uint8_t opMode, struct GasCfg *gascfg)
660094332d3Sopenharmony_ci{
661094332d3Sopenharmony_ci    int32_t ret = HDF_SUCCESS;
662094332d3Sopenharmony_ci    uint32_t meas_dur = 0; /* Calculate in us */
663094332d3Sopenharmony_ci    uint32_t meas_cycles;
664094332d3Sopenharmony_ci    uint8_t os_to_meas_cycles[6] = { 0, 1, 2, 4, 8, 16 };
665094332d3Sopenharmony_ci
666094332d3Sopenharmony_ci    CHECK_NULL_PTR_RETURN_VALUE(gascfg, HDF_ERR_INVALID_PARAM);
667094332d3Sopenharmony_ci
668094332d3Sopenharmony_ci    ret = BmeHalBoundaryCheck(data, &gascfg->tempOs, BME68X_OS_16X);
669094332d3Sopenharmony_ci    ret = BmeHalBoundaryCheck(data, &gascfg->presOs, BME68X_OS_16X);
670094332d3Sopenharmony_ci    ret = BmeHalBoundaryCheck(data, &gascfg->humOs, BME68X_OS_16X);
671094332d3Sopenharmony_ci    if (ret != HDF_SUCCESS) {
672094332d3Sopenharmony_ci        HDF_LOGE("%s: [BME688] boundary check failed", __func__);
673094332d3Sopenharmony_ci    }
674094332d3Sopenharmony_ci
675094332d3Sopenharmony_ci    meas_cycles = os_to_meas_cycles[gascfg->tempOs];
676094332d3Sopenharmony_ci    meas_cycles += os_to_meas_cycles[gascfg->presOs];
677094332d3Sopenharmony_ci    meas_cycles += os_to_meas_cycles[gascfg->humOs];
678094332d3Sopenharmony_ci
679094332d3Sopenharmony_ci    /* TPH measurement duration */
680094332d3Sopenharmony_ci    meas_dur = meas_cycles * BME_UINT32_C(1963);
681094332d3Sopenharmony_ci    meas_dur += BME_UINT32_C(477 * 4); /* TPH switching duration */
682094332d3Sopenharmony_ci    meas_dur += BME_UINT32_C(477 * 5); /* Gas measurement duration */
683094332d3Sopenharmony_ci
684094332d3Sopenharmony_ci    if (opMode != BME68X_PARALLEL_MODE) {
685094332d3Sopenharmony_ci        meas_dur += BME_UINT32_C(1000); /* Wake up duration of 1ms */
686094332d3Sopenharmony_ci    }
687094332d3Sopenharmony_ci
688094332d3Sopenharmony_ci    return meas_dur;
689094332d3Sopenharmony_ci}
690094332d3Sopenharmony_ci
691094332d3Sopenharmony_ci
692094332d3Sopenharmony_cistatic int32_t BmeHalSetConfig(struct SensorCfgData *data, struct bme688HeatrConf *conf,
693094332d3Sopenharmony_ci                               uint8_t opMode, uint8_t *nbConv)
694094332d3Sopenharmony_ci{
695094332d3Sopenharmony_ci    int32_t rc = HDF_SUCCESS;
696094332d3Sopenharmony_ci    uint8_t writeLen = 0;
697094332d3Sopenharmony_ci    uint8_t rh_reg_addr[10] = { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 };
698094332d3Sopenharmony_ci    uint8_t rh_reg_data[10] = { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 };
699094332d3Sopenharmony_ci    uint8_t gw_reg_addr[10] = { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 };
700094332d3Sopenharmony_ci    uint8_t gw_reg_data[10] = { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 };
701094332d3Sopenharmony_ci
702094332d3Sopenharmony_ci    switch (opMode) {
703094332d3Sopenharmony_ci        case BME68X_FORCED_MODE:
704094332d3Sopenharmony_ci            rh_reg_addr[0] = BME68X_REG_RES_HEAT0;
705094332d3Sopenharmony_ci            rh_reg_data[0] = BmeHalCalcResHeat(data, conf->heatr_temp);
706094332d3Sopenharmony_ci            gw_reg_addr[0] = BME68X_REG_GAS_WAIT0;
707094332d3Sopenharmony_ci            gw_reg_data[0] = BmeHalCalcGasWait(conf->heatr_dur);
708094332d3Sopenharmony_ci            (*nbConv) = 0;
709094332d3Sopenharmony_ci            writeLen = 1;
710094332d3Sopenharmony_ci            break;
711094332d3Sopenharmony_ci        default:
712094332d3Sopenharmony_ci            rc = HDF_ERR_INVALID_PARAM;
713094332d3Sopenharmony_ci    }
714094332d3Sopenharmony_ci
715094332d3Sopenharmony_ci    rc = BmeHalRegWriteOneByte(data, rh_reg_addr[0], rh_reg_data[0]);
716094332d3Sopenharmony_ci
717094332d3Sopenharmony_ci    rc = BmeHalRegWriteOneByte(data, gw_reg_addr[0], gw_reg_data[0]);
718094332d3Sopenharmony_ci
719094332d3Sopenharmony_ci    return rc;
720094332d3Sopenharmony_ci}
721094332d3Sopenharmony_ci
722094332d3Sopenharmony_cistatic int32_t Bme688SetHeatrConfig(struct SensorCfgData *data, struct bme688HeatrConf *conf, uint8_t opMode)
723094332d3Sopenharmony_ci{
724094332d3Sopenharmony_ci    int32_t rc;
725094332d3Sopenharmony_ci    uint8_t nb_conv = 0;
726094332d3Sopenharmony_ci    uint8_t hctrl, run_gas = 0;
727094332d3Sopenharmony_ci    uint8_t ctrl_gas_data[2];
728094332d3Sopenharmony_ci    uint8_t ctrl_gas_addr[2] = { BME68X_REG_CTRL_GAS_0, BME68X_REG_CTRL_GAS_1 };
729094332d3Sopenharmony_ci
730094332d3Sopenharmony_ci    CHECK_NULL_PTR_RETURN_VALUE(conf, HDF_ERR_INVALID_PARAM);
731094332d3Sopenharmony_ci
732094332d3Sopenharmony_ci    rc = Bme688SetOpMode(data, BME68X_SLEEP_MODE);
733094332d3Sopenharmony_ci
734094332d3Sopenharmony_ci    rc = BmeHalSetConfig(data, conf, opMode, &nb_conv);
735094332d3Sopenharmony_ci
736094332d3Sopenharmony_ci    rc = BmeHalRegRead(data, BME68X_REG_CTRL_GAS_0, ctrl_gas_data, 2);
737094332d3Sopenharmony_ci
738094332d3Sopenharmony_ci    if (conf->enable == BME68X_ENABLE) {
739094332d3Sopenharmony_ci        hctrl = BME68X_ENABLE_HEATER;
740094332d3Sopenharmony_ci        if (g_bme688State.variantId == BME68X_VARIANT_GAS_HIGH) {
741094332d3Sopenharmony_ci            run_gas = BME68X_ENABLE_GAS_MEAS_H;
742094332d3Sopenharmony_ci        } else {
743094332d3Sopenharmony_ci            run_gas = BME68X_ENABLE_GAS_MEAS_L;
744094332d3Sopenharmony_ci        }
745094332d3Sopenharmony_ci    } else {
746094332d3Sopenharmony_ci        hctrl = BME68X_DISABLE_HEATER;
747094332d3Sopenharmony_ci        run_gas = BME68X_DISABLE_GAS_MEAS;
748094332d3Sopenharmony_ci    }
749094332d3Sopenharmony_ci
750094332d3Sopenharmony_ci    ctrl_gas_data[0] = BME68X_SET_BITS(ctrl_gas_data[0], BME68X_HCTRL, hctrl);
751094332d3Sopenharmony_ci    ctrl_gas_data[1] = BME68X_SET_BITS_POS_0(ctrl_gas_data[1], BME68X_NBCONV, nb_conv);
752094332d3Sopenharmony_ci    ctrl_gas_data[1] = BME68X_SET_BITS(ctrl_gas_data[1], BME68X_RUN_GAS, run_gas);
753094332d3Sopenharmony_ci
754094332d3Sopenharmony_ci    rc = BmeHalRegWriteMulByte(data, ctrl_gas_addr, ctrl_gas_data, 2);
755094332d3Sopenharmony_ci
756094332d3Sopenharmony_ci    return rc;
757094332d3Sopenharmony_ci}
758094332d3Sopenharmony_ci
759094332d3Sopenharmony_cistatic int32_t BmeHalBoundaryCheck(struct SensorCfgData *data, uint8_t *value, uint8_t max)
760094332d3Sopenharmony_ci{
761094332d3Sopenharmony_ci    int32_t rc = HDF_SUCCESS;
762094332d3Sopenharmony_ci
763094332d3Sopenharmony_ci    CHECK_NULL_PTR_RETURN_VALUE(data, HDF_ERR_INVALID_PARAM);
764094332d3Sopenharmony_ci    if (value != NULL) {
765094332d3Sopenharmony_ci        if (*value > max) {
766094332d3Sopenharmony_ci            *value = max;
767094332d3Sopenharmony_ci        }
768094332d3Sopenharmony_ci    } else {
769094332d3Sopenharmony_ci        rc = HDF_ERR_INVALID_PARAM;
770094332d3Sopenharmony_ci    }
771094332d3Sopenharmony_ci
772094332d3Sopenharmony_ci    return rc;
773094332d3Sopenharmony_ci}
774094332d3Sopenharmony_ci
775094332d3Sopenharmony_cistatic int32_t Bme688SetConfig(struct SensorCfgData *data, struct GasCfg *gascfg)
776094332d3Sopenharmony_ci{
777094332d3Sopenharmony_ci    int32_t rc = HDF_SUCCESS;
778094332d3Sopenharmony_ci    uint8_t odr20 = 0, odr3 = 1;
779094332d3Sopenharmony_ci    uint8_t currentOpMode;
780094332d3Sopenharmony_ci
781094332d3Sopenharmony_ci    CHECK_NULL_PTR_RETURN_VALUE(gascfg, HDF_ERR_INVALID_PARAM);
782094332d3Sopenharmony_ci
783094332d3Sopenharmony_ci    uint8_t regArray[BME68X_LEN_CONFIG] = {0x71, 0x72, 0x73, 0x74, 0x75};
784094332d3Sopenharmony_ci    uint8_t dataArray[BME68X_LEN_CONFIG] = {0};
785094332d3Sopenharmony_ci
786094332d3Sopenharmony_ci    rc = Bme688GetOpMode(data, &currentOpMode);
787094332d3Sopenharmony_ci    if (rc != HDF_SUCCESS) {
788094332d3Sopenharmony_ci        HDF_LOGE("%s: bme688 get operation mode failed", __func__);
789094332d3Sopenharmony_ci    }
790094332d3Sopenharmony_ci
791094332d3Sopenharmony_ci    rc = Bme688SetOpMode(data, BME68X_SLEEP_MODE);
792094332d3Sopenharmony_ci    if (rc != HDF_SUCCESS) {
793094332d3Sopenharmony_ci        HDF_LOGE("%s: bme688 set sleep mode failed", __func__);
794094332d3Sopenharmony_ci    }
795094332d3Sopenharmony_ci
796094332d3Sopenharmony_ci    rc = BmeHalRegRead(data, regArray[0], dataArray, BME68X_LEN_CONFIG);
797094332d3Sopenharmony_ci    if (rc != HDF_SUCCESS) {
798094332d3Sopenharmony_ci        HDF_LOGE("%s, line : %d, bme688 read data array failed", __func__, __LINE__);
799094332d3Sopenharmony_ci    }
800094332d3Sopenharmony_ci
801094332d3Sopenharmony_ci    rc = BmeHalBoundaryCheck(data, &gascfg->filter, BME68X_FILTER_SIZE_127);
802094332d3Sopenharmony_ci    rc = BmeHalBoundaryCheck(data, &gascfg->tempOs, BME68X_OS_16X);
803094332d3Sopenharmony_ci    rc = BmeHalBoundaryCheck(data, &gascfg->presOs, BME68X_OS_16X);
804094332d3Sopenharmony_ci    rc = BmeHalBoundaryCheck(data, &gascfg->humOs, BME68X_OS_16X);
805094332d3Sopenharmony_ci    rc = BmeHalBoundaryCheck(data, &gascfg->odr, BME68X_ODR_NONE);
806094332d3Sopenharmony_ci    if (rc != HDF_SUCCESS) {
807094332d3Sopenharmony_ci        HDF_LOGE("%s: bme688 boundary check failed", __func__);
808094332d3Sopenharmony_ci    }
809094332d3Sopenharmony_ci
810094332d3Sopenharmony_ci    dataArray[4] = BME68X_SET_BITS(dataArray[4], BME68X_FILTER, gascfg->filter);
811094332d3Sopenharmony_ci    dataArray[3] = BME68X_SET_BITS(dataArray[3], BME68X_OST, gascfg->tempOs);
812094332d3Sopenharmony_ci    dataArray[3] = BME68X_SET_BITS(dataArray[3], BME68X_OSP, gascfg->presOs);
813094332d3Sopenharmony_ci    dataArray[1] = BME68X_SET_BITS_POS_0(dataArray[1], BME68X_OSH, gascfg->humOs);
814094332d3Sopenharmony_ci    if (gascfg->odr != BME68X_ODR_NONE) {
815094332d3Sopenharmony_ci        odr20 = gascfg->odr;
816094332d3Sopenharmony_ci        odr3 = 0;
817094332d3Sopenharmony_ci    }
818094332d3Sopenharmony_ci
819094332d3Sopenharmony_ci    dataArray[4] = BME68X_SET_BITS(dataArray[4], BME68X_ODR20, odr20);
820094332d3Sopenharmony_ci    dataArray[0] = BME68X_SET_BITS(dataArray[0], BME68X_ODR3, odr3);
821094332d3Sopenharmony_ci
822094332d3Sopenharmony_ci    rc = BmeHalRegWriteMulByte(data, regArray, dataArray, BME68X_LEN_CONFIG);
823094332d3Sopenharmony_ci    if (rc != HDF_SUCCESS) {
824094332d3Sopenharmony_ci        HDF_LOGE("%s: bme688 write config failed", __func__);
825094332d3Sopenharmony_ci    }
826094332d3Sopenharmony_ci
827094332d3Sopenharmony_ci    if (currentOpMode != BME68X_SLEEP_MODE) {
828094332d3Sopenharmony_ci        rc = Bme688SetOpMode(data, currentOpMode);
829094332d3Sopenharmony_ci    }
830094332d3Sopenharmony_ci
831094332d3Sopenharmony_ci    return rc;
832094332d3Sopenharmony_ci}
833094332d3Sopenharmony_ci
834094332d3Sopenharmony_cistatic int32_t BmeHalReadFieldData(struct SensorCfgData *data,
835094332d3Sopenharmony_ci                                   uint8_t index, struct GasFieldData *fieldData)
836094332d3Sopenharmony_ci{
837094332d3Sopenharmony_ci    uint8_t gas_range_l, gas_range_h, buff[BME68X_LEN_FIELD] = {0};
838094332d3Sopenharmony_ci    uint32_t adc_temp, adc_pres, tries = BME688_TRY_TIMES, rc = HDF_SUCCESS;
839094332d3Sopenharmony_ci    uint16_t adc_gas_res_low, adc_gas_res_high, adc_hum;
840094332d3Sopenharmony_ci    CHECK_NULL_PTR_RETURN_VALUE(fieldData, HDF_ERR_INVALID_PARAM);
841094332d3Sopenharmony_ci
842094332d3Sopenharmony_ci    while ((tries) && (rc == HDF_SUCCESS)) {
843094332d3Sopenharmony_ci        rc = BmeHalRegRead(data, (uint8_t)(BME68X_REG_FIELD0 + index * BME68X_LEN_FIELD_OFFSET),
844094332d3Sopenharmony_ci                           buff, (uint16_t)BME68X_LEN_FIELD);
845094332d3Sopenharmony_ci        if (rc != HDF_SUCCESS) {
846094332d3Sopenharmony_ci            HDF_LOGE("%s: bme688 read data failed", __func__);
847094332d3Sopenharmony_ci        }
848094332d3Sopenharmony_ci        fieldData->status = buff[0] & BME68X_NEW_DATA_MSK;
849094332d3Sopenharmony_ci        fieldData->gas_index = buff[0] & BME68X_GAS_INDEX_MSK;
850094332d3Sopenharmony_ci        fieldData->meas_index = buff[1];
851094332d3Sopenharmony_ci        /* read the raw data from the sensor */
852094332d3Sopenharmony_ci        adc_pres = (uint32_t)(((uint32_t)buff[2] * 4096) | ((uint32_t)buff[3] * 16) | ((uint32_t)buff[4] / 16));
853094332d3Sopenharmony_ci        adc_temp = (uint32_t)(((uint32_t)buff[5] * 4096) | ((uint32_t)buff[6] * 16) | ((uint32_t)buff[7] / 16));
854094332d3Sopenharmony_ci        adc_hum = (uint16_t)(((uint32_t)buff[8] * 256) | (uint32_t)buff[9]);
855094332d3Sopenharmony_ci        adc_gas_res_low = (uint16_t)((((uint32_t)buff[13]) * 4) | (((uint32_t)buff[14]) / 64));
856094332d3Sopenharmony_ci        adc_gas_res_high = (uint16_t)((((uint32_t)buff[15]) * 4) | (((uint32_t)buff[16]) / 64));
857094332d3Sopenharmony_ci        gas_range_l = buff[14] & BME68X_GAS_RANGE_MSK;
858094332d3Sopenharmony_ci        gas_range_h = buff[16] & BME68X_GAS_RANGE_MSK;
859094332d3Sopenharmony_ci
860094332d3Sopenharmony_ci        if (g_bme688State.variantId == BME68X_VARIANT_GAS_HIGH) {
861094332d3Sopenharmony_ci            fieldData->status |= buff[16] & BME68X_GASM_VALID_MSK;
862094332d3Sopenharmony_ci            fieldData->status |= buff[16] & BME68X_HEAT_STAB_MSK;
863094332d3Sopenharmony_ci        } else {
864094332d3Sopenharmony_ci            fieldData->status |= buff[14] & BME68X_GASM_VALID_MSK;
865094332d3Sopenharmony_ci            fieldData->status |= buff[14] & BME68X_HEAT_STAB_MSK;
866094332d3Sopenharmony_ci        }
867094332d3Sopenharmony_ci
868094332d3Sopenharmony_ci        if (fieldData->status & BME68X_NEW_DATA_MSK) {
869094332d3Sopenharmony_ci            rc = BmeHalRegRead(data, BME68X_REG_RES_HEAT0 + fieldData->gas_index, &fieldData->res_heat, 1);
870094332d3Sopenharmony_ci            rc |= BmeHalRegRead(data, BME68X_REG_IDAC_HEAT0 + fieldData->gas_index, &fieldData->idac, 1);
871094332d3Sopenharmony_ci            rc |= BmeHalRegRead(data, BME68X_REG_GAS_WAIT0 + fieldData->gas_index, &fieldData->gas_wait, 1);
872094332d3Sopenharmony_ci            if (rc != HDF_SUCCESS) {
873094332d3Sopenharmony_ci                HDF_LOGE("%s: bme688 read data failed", __func__);
874094332d3Sopenharmony_ci            }
875094332d3Sopenharmony_ci            fieldData->temperature = BmeHalCalcTemperature(data, adc_temp);
876094332d3Sopenharmony_ci            fieldData->pressure = BmeHalCalcPressure(data, adc_pres);
877094332d3Sopenharmony_ci            fieldData->humidity = BmeHalCalcHumidity(data, adc_hum);
878094332d3Sopenharmony_ci            if (g_bme688State.variantId == BME68X_VARIANT_GAS_HIGH) {
879094332d3Sopenharmony_ci                fieldData->gas_resistance = BmeHalCalcGasResistanceHigh(adc_gas_res_high, gas_range_h);
880094332d3Sopenharmony_ci            } else {
881094332d3Sopenharmony_ci                fieldData->gas_resistance = BmeHalCalcGasResistanceLow(data, adc_gas_res_low, gas_range_l);
882094332d3Sopenharmony_ci            }
883094332d3Sopenharmony_ci            break;
884094332d3Sopenharmony_ci        }
885094332d3Sopenharmony_ci        OsalMDelay(BME688_DELAY_10);
886094332d3Sopenharmony_ci        tries--;
887094332d3Sopenharmony_ci    }
888094332d3Sopenharmony_ci    return rc;
889094332d3Sopenharmony_ci}
890094332d3Sopenharmony_ci
891094332d3Sopenharmony_cistatic int32_t Bme688GetData(struct SensorCfgData *data, struct GasFieldData *fieldData, uint8_t opMode)
892094332d3Sopenharmony_ci{
893094332d3Sopenharmony_ci    int32_t ret;
894094332d3Sopenharmony_ci
895094332d3Sopenharmony_ci    CHECK_NULL_PTR_RETURN_VALUE(data, HDF_ERR_INVALID_PARAM);
896094332d3Sopenharmony_ci    CHECK_NULL_PTR_RETURN_VALUE(fieldData, HDF_ERR_INVALID_PARAM);
897094332d3Sopenharmony_ci
898094332d3Sopenharmony_ci    if (opMode == BME68X_FORCED_MODE) {
899094332d3Sopenharmony_ci        ret = BmeHalReadFieldData(data, 0, fieldData);
900094332d3Sopenharmony_ci        if (ret != HDF_SUCCESS) {
901094332d3Sopenharmony_ci            HDF_LOGE("%s: bme688 read field data failed", __func__);
902094332d3Sopenharmony_ci            return HDF_FAILURE;
903094332d3Sopenharmony_ci        }
904094332d3Sopenharmony_ci    } else {
905094332d3Sopenharmony_ci        HDF_LOGE("%s: sensor status error.", __func__);
906094332d3Sopenharmony_ci        return HDF_FAILURE;
907094332d3Sopenharmony_ci    }
908094332d3Sopenharmony_ci
909094332d3Sopenharmony_ci    return ret;
910094332d3Sopenharmony_ci}
911094332d3Sopenharmony_ci
912094332d3Sopenharmony_cistatic int32_t InitBme688(struct SensorCfgData *data)
913094332d3Sopenharmony_ci{
914094332d3Sopenharmony_ci    int32_t ret = HDF_SUCCESS;
915094332d3Sopenharmony_ci
916094332d3Sopenharmony_ci    CHECK_NULL_PTR_RETURN_VALUE(data, HDF_ERR_INVALID_PARAM);
917094332d3Sopenharmony_ci    ret = SetSensorRegCfgArray(&data->busCfg, data->regCfgGroup[SENSOR_INIT_GROUP]);
918094332d3Sopenharmony_ci    if (ret != HDF_SUCCESS) {
919094332d3Sopenharmony_ci        HDF_LOGE("%s: bme688 sensor init config failed", __func__);
920094332d3Sopenharmony_ci        return HDF_FAILURE;
921094332d3Sopenharmony_ci    }
922094332d3Sopenharmony_ci
923094332d3Sopenharmony_ci    ret = Bme688ReadVariantId(data);
924094332d3Sopenharmony_ci    if (ret != HDF_SUCCESS) {
925094332d3Sopenharmony_ci        HDF_LOGE("%s: bme688 sensor read variant id failed", __func__);
926094332d3Sopenharmony_ci        return HDF_FAILURE;
927094332d3Sopenharmony_ci    }
928094332d3Sopenharmony_ci
929094332d3Sopenharmony_ci    g_bme688State.workState = BME688_WORK_MODE_SUSPEND;
930094332d3Sopenharmony_ci    g_bme688State.inited = BME68X_DISABLE;
931094332d3Sopenharmony_ci
932094332d3Sopenharmony_ci    return ret;
933094332d3Sopenharmony_ci}
934094332d3Sopenharmony_ci
935094332d3Sopenharmony_cistatic int32_t DispatchBme688(struct HdfDeviceIoClient *client, int cmd, struct HdfSBuf *data, struct HdfSBuf *reply)
936094332d3Sopenharmony_ci{
937094332d3Sopenharmony_ci    (void)client;
938094332d3Sopenharmony_ci    (void)cmd;
939094332d3Sopenharmony_ci    (void)data;
940094332d3Sopenharmony_ci    (void)reply;
941094332d3Sopenharmony_ci
942094332d3Sopenharmony_ci    return HDF_SUCCESS;
943094332d3Sopenharmony_ci}
944094332d3Sopenharmony_ci
945094332d3Sopenharmony_cistatic int32_t Bme688BindDriver(struct HdfDeviceObject *device)
946094332d3Sopenharmony_ci{
947094332d3Sopenharmony_ci    OsalUDelay(BME688_DELAY_50);
948094332d3Sopenharmony_ci    CHECK_NULL_PTR_RETURN_VALUE(device, HDF_ERR_INVALID_PARAM);
949094332d3Sopenharmony_ci
950094332d3Sopenharmony_ci    struct Bme688DrvData *drvData = (struct Bme688DrvData *)OsalMemCalloc(sizeof(*drvData));
951094332d3Sopenharmony_ci    if (drvData == NULL) {
952094332d3Sopenharmony_ci        HDF_LOGE("%s: Malloc Bme688 drv data fail", __func__);
953094332d3Sopenharmony_ci        return HDF_ERR_MALLOC_FAIL;
954094332d3Sopenharmony_ci    }
955094332d3Sopenharmony_ci
956094332d3Sopenharmony_ci    drvData->ioService.Dispatch = DispatchBme688;
957094332d3Sopenharmony_ci    drvData->device = device;
958094332d3Sopenharmony_ci    device->service = &drvData->ioService;
959094332d3Sopenharmony_ci    g_bme688DrvData = drvData;
960094332d3Sopenharmony_ci
961094332d3Sopenharmony_ci    return HDF_SUCCESS;
962094332d3Sopenharmony_ci}
963094332d3Sopenharmony_ci
964094332d3Sopenharmony_cistatic int32_t Bme688InitDriver(struct HdfDeviceObject *device)
965094332d3Sopenharmony_ci{
966094332d3Sopenharmony_ci    int32_t ret;
967094332d3Sopenharmony_ci    struct GasOpsCall ops;
968094332d3Sopenharmony_ci    CHECK_NULL_PTR_RETURN_VALUE(device, HDF_ERR_INVALID_PARAM);
969094332d3Sopenharmony_ci    struct Bme688DrvData *drvData = (struct Bme688DrvData *)device->service;
970094332d3Sopenharmony_ci    CHECK_NULL_PTR_RETURN_VALUE(drvData, HDF_ERR_INVALID_PARAM);
971094332d3Sopenharmony_ci    CHECK_NULL_PTR_RETURN_VALUE(device->property, HDF_ERR_INVALID_PARAM);
972094332d3Sopenharmony_ci
973094332d3Sopenharmony_ci    drvData->sensorCfg = GasCreateCfgData(device->property);
974094332d3Sopenharmony_ci    if (drvData->sensorCfg == NULL || drvData->sensorCfg->root == NULL) {
975094332d3Sopenharmony_ci        HDF_LOGD("%s: Creating gascfg failed because detection failed", __func__);
976094332d3Sopenharmony_ci        return HDF_ERR_NOT_SUPPORT;
977094332d3Sopenharmony_ci    }
978094332d3Sopenharmony_ci
979094332d3Sopenharmony_ci    ops.Init = NULL;
980094332d3Sopenharmony_ci    ops.ReadData = ReadBme688Data;
981094332d3Sopenharmony_ci    ret = GasRegisterChipOps(&ops);
982094332d3Sopenharmony_ci    if (ret != HDF_SUCCESS) {
983094332d3Sopenharmony_ci        HDF_LOGE("%s: Register bme688 gas failed", __func__);
984094332d3Sopenharmony_ci        return HDF_FAILURE;
985094332d3Sopenharmony_ci    }
986094332d3Sopenharmony_ci
987094332d3Sopenharmony_ci    ret = Bme688SoftReset(drvData->sensorCfg);
988094332d3Sopenharmony_ci    if (ret != HDF_SUCCESS) {
989094332d3Sopenharmony_ci        HDF_LOGE("%s: bme688 dump data failed!", __func__);
990094332d3Sopenharmony_ci    }
991094332d3Sopenharmony_ci
992094332d3Sopenharmony_ci    // validate chip id
993094332d3Sopenharmony_ci    ret = Bme688ValChipId(drvData->sensorCfg);
994094332d3Sopenharmony_ci    if (ret != HDF_SUCCESS) {
995094332d3Sopenharmony_ci        return ret;
996094332d3Sopenharmony_ci    }
997094332d3Sopenharmony_ci
998094332d3Sopenharmony_ci    ret = Bme688GetCalibData(drvData->sensorCfg, &g_calibData);
999094332d3Sopenharmony_ci    if (ret != HDF_SUCCESS) {
1000094332d3Sopenharmony_ci        HDF_LOGE("%s: get calibration data in init process failed", __func__);
1001094332d3Sopenharmony_ci        return HDF_FAILURE;
1002094332d3Sopenharmony_ci    }
1003094332d3Sopenharmony_ci
1004094332d3Sopenharmony_ci    ret = InitBme688(drvData->sensorCfg);
1005094332d3Sopenharmony_ci    if (ret != HDF_SUCCESS) {
1006094332d3Sopenharmony_ci        HDF_LOGE("%s: Init bme688 gas failed", __func__);
1007094332d3Sopenharmony_ci        return HDF_FAILURE;
1008094332d3Sopenharmony_ci    }
1009094332d3Sopenharmony_ci
1010094332d3Sopenharmony_ci    return HDF_SUCCESS;
1011094332d3Sopenharmony_ci}
1012094332d3Sopenharmony_ci
1013094332d3Sopenharmony_cistatic void Bme688ReleaseDriver(struct HdfDeviceObject *device)
1014094332d3Sopenharmony_ci{
1015094332d3Sopenharmony_ci    CHECK_NULL_PTR_RETURN(device);
1016094332d3Sopenharmony_ci
1017094332d3Sopenharmony_ci    struct Bme688DrvData *drvData = (struct Bme688DrvData *)device->service;
1018094332d3Sopenharmony_ci    CHECK_NULL_PTR_RETURN(drvData);
1019094332d3Sopenharmony_ci
1020094332d3Sopenharmony_ci    if (drvData->sensorCfg != NULL) {
1021094332d3Sopenharmony_ci        GasReleaseCfgData(drvData->sensorCfg);
1022094332d3Sopenharmony_ci        drvData->sensorCfg = NULL;
1023094332d3Sopenharmony_ci    }
1024094332d3Sopenharmony_ci
1025094332d3Sopenharmony_ci    OsalMemFree(drvData);
1026094332d3Sopenharmony_ci}
1027094332d3Sopenharmony_ci
1028094332d3Sopenharmony_cistruct HdfDriverEntry g_gasBme688DevEntry = {
1029094332d3Sopenharmony_ci    .moduleVersion  = 1,
1030094332d3Sopenharmony_ci    .moduleName     = "HDF_SENSOR_GAS_BME688",
1031094332d3Sopenharmony_ci    .Bind           = Bme688BindDriver,
1032094332d3Sopenharmony_ci    .Init           = Bme688InitDriver,
1033094332d3Sopenharmony_ci    .Release        = Bme688ReleaseDriver,
1034094332d3Sopenharmony_ci};
1035094332d3Sopenharmony_ci
1036094332d3Sopenharmony_ciHDF_INIT(g_gasBme688DevEntry);
1037