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, ®v, 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, ®v, 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, ¤tOpMode); 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