uses BBC micro:bit to measure and display indoor air quality using Bosch BME680 and/or Sensirion SGP30

Dependencies:   microbit

uses Bosch BME680 and/or Sensirion SGP30 sensors to measure indor air quality

sensors should be connected to BBC micro:bit using i2c

commands are received and data is being sent using uBit / nordic radio protocol

display ---

last line always indicates: - first dot: bme680 detected - second dot: sgp30 detected - third dot: sgp 30 setting humidity/temperature - fourth dor: sgp30 measuring - fith dot: bme680 measuring

the detect dots should be in a stable state (not blinking) the measuring dots should be blinking (constant light means: measurement failed)

if only one bme680 is present: - first 3 lines indicate gas resistence (air quality / more dots == worse quality) - fourth line indicates humidity level

if only sgp30 is present: - first two lines indicate SGP30 VOC level - third and fourth line indicate sgp30 CO2 level

if both sensors are present: - first line indicates SGP30 VOC level - second line line indicates sgp30 CO2 level - third line indicates bme680 gas resistence (air quality) - fourth line indicates bme 680 humidity level

buttons - B display state, switches betweeen - full bright - low light - display off

AB reset sgp30 baseline in non volatile storage

data logging -- during measurements the minimum and mximum values for each measured value (temperature, air pressure, humidity,gas resistance, VOC, CO2) are being stored in non volatile storage those (and the last measurement results) are being shown when btn A has been pressed

Committer:
jsa1969
Date:
Tue Dec 04 08:42:15 2018 +0000
Revision:
3:6084ab9ff0c9
Parent:
2:544117df8c65
Child:
14:71060505061e
handle cases where only one sensor is present

Who changed what in which revision?

UserRevisionLine numberNew contents of line
jsa1969 0:cef60cc92da0 1 #include "bme680.h"
jsa1969 0:cef60cc92da0 2
jsa1969 0:cef60cc92da0 3 Bme680::Bme680(I2cCallbacks *callbacks) {
jsa1969 2:544117df8c65 4 initialize(callbacks,0);
jsa1969 2:544117df8c65 5 }
jsa1969 2:544117df8c65 6
jsa1969 2:544117df8c65 7 Bme680::Bme680(I2cCallbacks *callbacks, uint32_t gas_resistance_max) {
jsa1969 2:544117df8c65 8 initialize(callbacks, gas_resistance_max);
jsa1969 2:544117df8c65 9 }
jsa1969 2:544117df8c65 10
jsa1969 2:544117df8c65 11 void Bme680::initialize(I2cCallbacks *callbacks, uint32_t gas_resistance_max) {
jsa1969 0:cef60cc92da0 12 _dev = new bme680_dev;
jsa1969 0:cef60cc92da0 13 _dev->dev_id = BME680_I2C_ADDR_PRIMARY<<1;
jsa1969 0:cef60cc92da0 14 _i2cCallbacks = callbacks;
jsa1969 2:544117df8c65 15 _gas_resistance_max = gas_resistance_max;
jsa1969 0:cef60cc92da0 16 }
jsa1969 0:cef60cc92da0 17
jsa1969 0:cef60cc92da0 18 int Bme680::init() {
jsa1969 0:cef60cc92da0 19 int rslt = soft_reset();
jsa1969 0:cef60cc92da0 20 if (rslt!=BME680_OK) return rslt;
jsa1969 0:cef60cc92da0 21
jsa1969 0:cef60cc92da0 22 rslt = get_regs(BME680_CHIP_ID_ADDR, &(_dev->chip_id), 1);
jsa1969 0:cef60cc92da0 23 if (rslt!=BME680_OK) return rslt;
jsa1969 0:cef60cc92da0 24
jsa1969 0:cef60cc92da0 25 if (_dev->chip_id == BME680_CHIP_ID) {
jsa1969 0:cef60cc92da0 26 rslt = get_calib_data();
jsa1969 0:cef60cc92da0 27 } else {
jsa1969 0:cef60cc92da0 28 rslt = BME680_E_DEV_NOT_FOUND;
jsa1969 0:cef60cc92da0 29 }
jsa1969 0:cef60cc92da0 30
jsa1969 0:cef60cc92da0 31 return rslt;
jsa1969 0:cef60cc92da0 32 }
jsa1969 0:cef60cc92da0 33
jsa1969 0:cef60cc92da0 34 int Bme680::measure(struct bme680_field_data* data, int ambTemp, uint16_t heatr_dur, uint16_t heatr_temp){
jsa1969 0:cef60cc92da0 35 int rslt = null_ptr_check();
jsa1969 0:cef60cc92da0 36 if (rslt!=BME680_OK) return rslt;
jsa1969 0:cef60cc92da0 37
jsa1969 0:cef60cc92da0 38 _dev->amb_temp = ambTemp;
jsa1969 0:cef60cc92da0 39 _dev->power_mode = BME680_FORCED_MODE;
jsa1969 0:cef60cc92da0 40
jsa1969 0:cef60cc92da0 41 _dev->tph_sett.os_hum = BME680_OS_1X;
jsa1969 0:cef60cc92da0 42 _dev->tph_sett.os_pres = BME680_OS_16X;
jsa1969 0:cef60cc92da0 43 _dev->tph_sett.os_temp = BME680_OS_2X;
jsa1969 0:cef60cc92da0 44
jsa1969 0:cef60cc92da0 45 _dev->gas_sett.run_gas = BME680_ENABLE_GAS_MEAS;
jsa1969 0:cef60cc92da0 46 _dev->gas_sett.heatr_dur = heatr_dur;
jsa1969 0:cef60cc92da0 47 _dev->gas_sett.heatr_temp = heatr_temp;
jsa1969 0:cef60cc92da0 48
jsa1969 0:cef60cc92da0 49 uint16_t settings_sel = BME680_OST_SEL | BME680_OSP_SEL | BME680_OSH_SEL | BME680_GAS_SENSOR_SEL;
jsa1969 0:cef60cc92da0 50
jsa1969 0:cef60cc92da0 51 uint16_t profile_dur = 0;
jsa1969 0:cef60cc92da0 52 get_profile_dur(&profile_dur);
jsa1969 0:cef60cc92da0 53
jsa1969 0:cef60cc92da0 54 rslt = set_sensor_settings(settings_sel);
jsa1969 0:cef60cc92da0 55
jsa1969 0:cef60cc92da0 56 if (rslt == BME680_OK) {
jsa1969 0:cef60cc92da0 57 rslt = set_sensor_mode();
jsa1969 0:cef60cc92da0 58 _i2cCallbacks->delay_ms(profile_dur);
jsa1969 0:cef60cc92da0 59 rslt = get_sensor_data(data);
jsa1969 0:cef60cc92da0 60
jsa1969 0:cef60cc92da0 61 if (rslt == BME680_OK) {
jsa1969 0:cef60cc92da0 62 rslt = analyze_sensor_data(data);
jsa1969 0:cef60cc92da0 63 }
jsa1969 0:cef60cc92da0 64 }
jsa1969 0:cef60cc92da0 65
jsa1969 2:544117df8c65 66 if (rslt == BME680_OK && _gas_resistance_max < data->gas_resistance) {
jsa1969 2:544117df8c65 67 _gas_resistance_max = data->gas_resistance;
jsa1969 2:544117df8c65 68 }
jsa1969 0:cef60cc92da0 69
jsa1969 0:cef60cc92da0 70 return rslt;
jsa1969 0:cef60cc92da0 71 }
jsa1969 0:cef60cc92da0 72
jsa1969 2:544117df8c65 73 uint32_t Bme680::gasResistanceMax() {
jsa1969 2:544117df8c65 74 return _gas_resistance_max;
jsa1969 2:544117df8c65 75 }
jsa1969 2:544117df8c65 76
jsa1969 3:6084ab9ff0c9 77 void Bme680::resetGasResistenceMax() {
jsa1969 3:6084ab9ff0c9 78 _gas_resistance_max = 0;
jsa1969 3:6084ab9ff0c9 79 }
jsa1969 3:6084ab9ff0c9 80
jsa1969 0:cef60cc92da0 81 int Bme680::analyze_sensor_data(struct bme680_field_data *data)
jsa1969 0:cef60cc92da0 82 {
jsa1969 0:cef60cc92da0 83 int rslt = BME680_OK;
jsa1969 0:cef60cc92da0 84 uint8_t self_test_failed = 0;
jsa1969 0:cef60cc92da0 85
jsa1969 0:cef60cc92da0 86 const int16_t MIN_TEMPERATURE = INT16_C(0); /* 0 degree Celsius */
jsa1969 0:cef60cc92da0 87 const int16_t MAX_TEMPERATURE = INT16_C(6000); /* 60 degree Celsius */
jsa1969 0:cef60cc92da0 88
jsa1969 0:cef60cc92da0 89 const uint32_t MIN_PRESSURE = UINT32_C(90000); /* 900 hecto Pascals */
jsa1969 0:cef60cc92da0 90 const uint32_t MAX_PRESSURE = UINT32_C(110000); /* 1100 hecto Pascals */
jsa1969 0:cef60cc92da0 91
jsa1969 0:cef60cc92da0 92 const uint32_t MIN_HUMIDITY = UINT32_C(1000); /* 20% relative humidity */
jsa1969 0:cef60cc92da0 93 const uint32_t MAX_HUMIDITY = UINT32_C(100000); /* 80% relative humidity*/
jsa1969 0:cef60cc92da0 94
jsa1969 0:cef60cc92da0 95 if ((data->temperature < MIN_TEMPERATURE) || (data->temperature > MAX_TEMPERATURE))
jsa1969 0:cef60cc92da0 96 self_test_failed++;
jsa1969 0:cef60cc92da0 97
jsa1969 0:cef60cc92da0 98 if ((data->pressure < MIN_PRESSURE) || (data->pressure > MAX_PRESSURE))
jsa1969 0:cef60cc92da0 99 self_test_failed++;
jsa1969 0:cef60cc92da0 100
jsa1969 0:cef60cc92da0 101 if ((data->humidity < MIN_HUMIDITY) || (data->humidity > MAX_HUMIDITY))
jsa1969 0:cef60cc92da0 102 self_test_failed++;
jsa1969 0:cef60cc92da0 103
jsa1969 0:cef60cc92da0 104 if (!(data->status & BME680_GASM_VALID_MSK))
jsa1969 0:cef60cc92da0 105 self_test_failed++;
jsa1969 0:cef60cc92da0 106
jsa1969 0:cef60cc92da0 107 if (self_test_failed)
jsa1969 0:cef60cc92da0 108 rslt = BME680_W_SELF_TEST_FAILED;
jsa1969 0:cef60cc92da0 109
jsa1969 0:cef60cc92da0 110 return rslt;
jsa1969 0:cef60cc92da0 111 }
jsa1969 0:cef60cc92da0 112
jsa1969 0:cef60cc92da0 113 int Bme680::soft_reset() {
jsa1969 0:cef60cc92da0 114 int rslt = null_ptr_check();
jsa1969 0:cef60cc92da0 115 if (rslt!=BME680_OK) return rslt;
jsa1969 0:cef60cc92da0 116
jsa1969 0:cef60cc92da0 117 uint8_t reg_addr = BME680_SOFT_RESET_ADDR;
jsa1969 0:cef60cc92da0 118 uint8_t soft_rst_cmd = BME680_SOFT_RESET_CMD;
jsa1969 0:cef60cc92da0 119 rslt = set_regs(&reg_addr, &soft_rst_cmd, 1);
jsa1969 0:cef60cc92da0 120
jsa1969 0:cef60cc92da0 121 if (rslt==BME680_OK) {
jsa1969 0:cef60cc92da0 122 _i2cCallbacks->delay_ms(BME680_RESET_PERIOD);
jsa1969 0:cef60cc92da0 123 }
jsa1969 0:cef60cc92da0 124
jsa1969 0:cef60cc92da0 125 return rslt;
jsa1969 0:cef60cc92da0 126 }
jsa1969 0:cef60cc92da0 127
jsa1969 0:cef60cc92da0 128 int Bme680::get_regs(uint8_t reg_addr, uint8_t *reg_data, uint16_t len)
jsa1969 0:cef60cc92da0 129 {
jsa1969 0:cef60cc92da0 130 int rslt = null_ptr_check();
jsa1969 0:cef60cc92da0 131 if (rslt!=BME680_OK) return rslt;
jsa1969 0:cef60cc92da0 132
jsa1969 0:cef60cc92da0 133 _dev->com_rslt = _i2cCallbacks->read(_dev->dev_id, reg_addr, reg_data, len);
jsa1969 0:cef60cc92da0 134 if (_dev->com_rslt != 0)
jsa1969 0:cef60cc92da0 135 rslt = BME680_E_COM_FAIL;
jsa1969 0:cef60cc92da0 136 return rslt;
jsa1969 0:cef60cc92da0 137 }
jsa1969 0:cef60cc92da0 138
jsa1969 0:cef60cc92da0 139
jsa1969 0:cef60cc92da0 140 /*
jsa1969 0:cef60cc92da0 141 int8_t Bme680::get_mem_page()
jsa1969 0:cef60cc92da0 142 {
jsa1969 0:cef60cc92da0 143 int8_t rslt = null_ptr_check();
jsa1969 0:cef60cc92da0 144 if (rslt!=BME680_OK) return rslt;
jsa1969 0:cef60cc92da0 145
jsa1969 0:cef60cc92da0 146 uint8_t reg;
jsa1969 0:cef60cc92da0 147
jsa1969 0:cef60cc92da0 148 _dev->com_rslt = _i2cCallbacks->read(_dev->dev_id, BME680_MEM_PAGE_ADDR | BME680_SPI_RD_MSK, &reg, 1);
jsa1969 0:cef60cc92da0 149 if (_dev->com_rslt != 0)
jsa1969 0:cef60cc92da0 150 rslt = BME680_E_COM_FAIL;
jsa1969 0:cef60cc92da0 151 else
jsa1969 0:cef60cc92da0 152 _dev->mem_page = reg & BME680_MEM_PAGE_MSK;
jsa1969 0:cef60cc92da0 153
jsa1969 0:cef60cc92da0 154 return rslt;
jsa1969 0:cef60cc92da0 155 }
jsa1969 0:cef60cc92da0 156 */
jsa1969 0:cef60cc92da0 157
jsa1969 0:cef60cc92da0 158 int Bme680::set_regs(const uint8_t *reg_addr, const uint8_t *reg_data, uint8_t len)
jsa1969 0:cef60cc92da0 159 {
jsa1969 0:cef60cc92da0 160 int rslt = null_ptr_check();
jsa1969 0:cef60cc92da0 161 if (rslt!=BME680_OK) return rslt;
jsa1969 0:cef60cc92da0 162
jsa1969 0:cef60cc92da0 163 /* Length of the temporary buffer is 2*(length of register)*/
jsa1969 0:cef60cc92da0 164 uint8_t tmp_buff[BME680_TMP_BUFFER_LENGTH] = { 0 };
jsa1969 0:cef60cc92da0 165 uint16_t index;
jsa1969 0:cef60cc92da0 166
jsa1969 0:cef60cc92da0 167 if ((len > 0) && (len < BME680_TMP_BUFFER_LENGTH / 2)) {
jsa1969 0:cef60cc92da0 168 /* Interleave the 2 arrays */
jsa1969 0:cef60cc92da0 169 for (index = 0; index < len; index++) {
jsa1969 0:cef60cc92da0 170 tmp_buff[(2 * index)] = reg_addr[index];
jsa1969 0:cef60cc92da0 171 tmp_buff[(2 * index) + 1] = reg_data[index];
jsa1969 0:cef60cc92da0 172 }
jsa1969 0:cef60cc92da0 173 /* Write the interleaved array */
jsa1969 0:cef60cc92da0 174 _dev->com_rslt = _i2cCallbacks->write(_dev->dev_id, tmp_buff[0], &tmp_buff[1], (2 * len) - 1);
jsa1969 0:cef60cc92da0 175 if (_dev->com_rslt != 0) {
jsa1969 0:cef60cc92da0 176 rslt = BME680_E_COM_FAIL;
jsa1969 0:cef60cc92da0 177 }
jsa1969 0:cef60cc92da0 178 } else {
jsa1969 0:cef60cc92da0 179 rslt = BME680_E_INVALID_LENGTH;
jsa1969 0:cef60cc92da0 180 }
jsa1969 0:cef60cc92da0 181
jsa1969 0:cef60cc92da0 182 return rslt;
jsa1969 0:cef60cc92da0 183 }
jsa1969 0:cef60cc92da0 184
jsa1969 0:cef60cc92da0 185 int Bme680::null_ptr_check()
jsa1969 0:cef60cc92da0 186 {
jsa1969 0:cef60cc92da0 187 if (_dev == NULL || _i2cCallbacks == NULL) {
jsa1969 0:cef60cc92da0 188 /* Device structure pointer is not valid */
jsa1969 0:cef60cc92da0 189 return BME680_E_NULL_PTR;
jsa1969 0:cef60cc92da0 190 } else {
jsa1969 0:cef60cc92da0 191 /* Device structure is fine */
jsa1969 0:cef60cc92da0 192 return BME680_OK;
jsa1969 0:cef60cc92da0 193 }
jsa1969 0:cef60cc92da0 194 }
jsa1969 0:cef60cc92da0 195
jsa1969 0:cef60cc92da0 196 int Bme680::get_calib_data()
jsa1969 0:cef60cc92da0 197 {
jsa1969 0:cef60cc92da0 198 int rslt;
jsa1969 0:cef60cc92da0 199 uint8_t coeff_array[BME680_COEFF_SIZE] = { 0 };
jsa1969 0:cef60cc92da0 200 uint8_t temp_var = 0; /* Temporary variable */
jsa1969 0:cef60cc92da0 201
jsa1969 0:cef60cc92da0 202 /* Check for null pointer in the device structure*/
jsa1969 0:cef60cc92da0 203 rslt = null_ptr_check();
jsa1969 0:cef60cc92da0 204 if (rslt == BME680_OK) {
jsa1969 0:cef60cc92da0 205 rslt = get_regs(BME680_COEFF_ADDR1, coeff_array, BME680_COEFF_ADDR1_LEN);
jsa1969 0:cef60cc92da0 206 /* Append the second half in the same array */
jsa1969 0:cef60cc92da0 207 if (rslt == BME680_OK)
jsa1969 0:cef60cc92da0 208 rslt = get_regs(BME680_COEFF_ADDR2, &coeff_array[BME680_COEFF_ADDR1_LEN]
jsa1969 0:cef60cc92da0 209 , BME680_COEFF_ADDR2_LEN);
jsa1969 0:cef60cc92da0 210
jsa1969 0:cef60cc92da0 211 /* Temperature related coefficients */
jsa1969 0:cef60cc92da0 212 _dev->calib.par_t1 = (uint16_t) (BME680_CONCAT_BYTES(coeff_array[BME680_T1_MSB_REG],
jsa1969 0:cef60cc92da0 213 coeff_array[BME680_T1_LSB_REG]));
jsa1969 0:cef60cc92da0 214 _dev->calib.par_t2 = (int16_t) (BME680_CONCAT_BYTES(coeff_array[BME680_T2_MSB_REG],
jsa1969 0:cef60cc92da0 215 coeff_array[BME680_T2_LSB_REG]));
jsa1969 0:cef60cc92da0 216 _dev->calib.par_t3 = (int8_t) (coeff_array[BME680_T3_REG]);
jsa1969 0:cef60cc92da0 217
jsa1969 0:cef60cc92da0 218 /* Pressure related coefficients */
jsa1969 0:cef60cc92da0 219 _dev->calib.par_p1 = (uint16_t) (BME680_CONCAT_BYTES(coeff_array[BME680_P1_MSB_REG],
jsa1969 0:cef60cc92da0 220 coeff_array[BME680_P1_LSB_REG]));
jsa1969 0:cef60cc92da0 221 _dev->calib.par_p2 = (int16_t) (BME680_CONCAT_BYTES(coeff_array[BME680_P2_MSB_REG],
jsa1969 0:cef60cc92da0 222 coeff_array[BME680_P2_LSB_REG]));
jsa1969 0:cef60cc92da0 223 _dev->calib.par_p3 = (int8_t) coeff_array[BME680_P3_REG];
jsa1969 0:cef60cc92da0 224 _dev->calib.par_p4 = (int16_t) (BME680_CONCAT_BYTES(coeff_array[BME680_P4_MSB_REG],
jsa1969 0:cef60cc92da0 225 coeff_array[BME680_P4_LSB_REG]));
jsa1969 0:cef60cc92da0 226 _dev->calib.par_p5 = (int16_t) (BME680_CONCAT_BYTES(coeff_array[BME680_P5_MSB_REG],
jsa1969 0:cef60cc92da0 227 coeff_array[BME680_P5_LSB_REG]));
jsa1969 0:cef60cc92da0 228 _dev->calib.par_p6 = (int8_t) (coeff_array[BME680_P6_REG]);
jsa1969 0:cef60cc92da0 229 _dev->calib.par_p7 = (int8_t) (coeff_array[BME680_P7_REG]);
jsa1969 0:cef60cc92da0 230 _dev->calib.par_p8 = (int16_t) (BME680_CONCAT_BYTES(coeff_array[BME680_P8_MSB_REG],
jsa1969 0:cef60cc92da0 231 coeff_array[BME680_P8_LSB_REG]));
jsa1969 0:cef60cc92da0 232 _dev->calib.par_p9 = (int16_t) (BME680_CONCAT_BYTES(coeff_array[BME680_P9_MSB_REG],
jsa1969 0:cef60cc92da0 233 coeff_array[BME680_P9_LSB_REG]));
jsa1969 0:cef60cc92da0 234 _dev->calib.par_p10 = (uint8_t) (coeff_array[BME680_P10_REG]);
jsa1969 0:cef60cc92da0 235
jsa1969 0:cef60cc92da0 236 /* Humidity related coefficients */
jsa1969 0:cef60cc92da0 237 _dev->calib.par_h1 = (uint16_t) (((uint16_t) coeff_array[BME680_H1_MSB_REG] << BME680_HUM_REG_SHIFT_VAL)
jsa1969 0:cef60cc92da0 238 | (coeff_array[BME680_H1_LSB_REG] & BME680_BIT_H1_DATA_MSK));
jsa1969 0:cef60cc92da0 239 _dev->calib.par_h2 = (uint16_t) (((uint16_t) coeff_array[BME680_H2_MSB_REG] << BME680_HUM_REG_SHIFT_VAL)
jsa1969 0:cef60cc92da0 240 | ((coeff_array[BME680_H2_LSB_REG]) >> BME680_HUM_REG_SHIFT_VAL));
jsa1969 0:cef60cc92da0 241 _dev->calib.par_h3 = (int8_t) coeff_array[BME680_H3_REG];
jsa1969 0:cef60cc92da0 242 _dev->calib.par_h4 = (int8_t) coeff_array[BME680_H4_REG];
jsa1969 0:cef60cc92da0 243 _dev->calib.par_h5 = (int8_t) coeff_array[BME680_H5_REG];
jsa1969 0:cef60cc92da0 244 _dev->calib.par_h6 = (uint8_t) coeff_array[BME680_H6_REG];
jsa1969 0:cef60cc92da0 245 _dev->calib.par_h7 = (int8_t) coeff_array[BME680_H7_REG];
jsa1969 0:cef60cc92da0 246
jsa1969 0:cef60cc92da0 247 /* Gas heater related coefficients */
jsa1969 0:cef60cc92da0 248 _dev->calib.par_gh1 = (int8_t) coeff_array[BME680_GH1_REG];
jsa1969 0:cef60cc92da0 249 _dev->calib.par_gh2 = (int16_t) (BME680_CONCAT_BYTES(coeff_array[BME680_GH2_MSB_REG],
jsa1969 0:cef60cc92da0 250 coeff_array[BME680_GH2_LSB_REG]));
jsa1969 0:cef60cc92da0 251 _dev->calib.par_gh3 = (int8_t) coeff_array[BME680_GH3_REG];
jsa1969 0:cef60cc92da0 252
jsa1969 0:cef60cc92da0 253 /* Other coefficients */
jsa1969 0:cef60cc92da0 254 if (rslt == BME680_OK) {
jsa1969 0:cef60cc92da0 255 rslt = get_regs(BME680_ADDR_RES_HEAT_RANGE_ADDR, &temp_var, 1);
jsa1969 0:cef60cc92da0 256
jsa1969 0:cef60cc92da0 257 _dev->calib.res_heat_range = ((temp_var & BME680_RHRANGE_MSK) / 16);
jsa1969 0:cef60cc92da0 258 if (rslt == BME680_OK) {
jsa1969 0:cef60cc92da0 259 rslt = get_regs(BME680_ADDR_RES_HEAT_VAL_ADDR, &temp_var, 1);
jsa1969 0:cef60cc92da0 260
jsa1969 0:cef60cc92da0 261 _dev->calib.res_heat_val = (int8_t) temp_var;
jsa1969 0:cef60cc92da0 262 if (rslt == BME680_OK)
jsa1969 0:cef60cc92da0 263 rslt = get_regs(BME680_ADDR_RANGE_SW_ERR_ADDR, &temp_var, 1);
jsa1969 0:cef60cc92da0 264 }
jsa1969 0:cef60cc92da0 265 }
jsa1969 0:cef60cc92da0 266 _dev->calib.range_sw_err = ((int8_t) temp_var & (int8_t) BME680_RSERROR_MSK) / 16;
jsa1969 0:cef60cc92da0 267 }
jsa1969 0:cef60cc92da0 268
jsa1969 0:cef60cc92da0 269 return rslt;
jsa1969 0:cef60cc92da0 270 }
jsa1969 0:cef60cc92da0 271
jsa1969 0:cef60cc92da0 272 void Bme680::set_profile_dur(uint16_t duration)
jsa1969 0:cef60cc92da0 273 {
jsa1969 0:cef60cc92da0 274 uint32_t tph_dur; /* Calculate in us */
jsa1969 0:cef60cc92da0 275 uint32_t meas_cycles;
jsa1969 0:cef60cc92da0 276 uint8_t os_to_meas_cycles[6] = {0, 1, 2, 4, 8, 16};
jsa1969 0:cef60cc92da0 277
jsa1969 0:cef60cc92da0 278 meas_cycles = os_to_meas_cycles[_dev->tph_sett.os_temp];
jsa1969 0:cef60cc92da0 279 meas_cycles += os_to_meas_cycles[_dev->tph_sett.os_pres];
jsa1969 0:cef60cc92da0 280 meas_cycles += os_to_meas_cycles[_dev->tph_sett.os_hum];
jsa1969 0:cef60cc92da0 281
jsa1969 0:cef60cc92da0 282 /* TPH measurement duration */
jsa1969 0:cef60cc92da0 283 tph_dur = meas_cycles * UINT32_C(1963);
jsa1969 0:cef60cc92da0 284 tph_dur += UINT32_C(477 * 4); /* TPH switching duration */
jsa1969 0:cef60cc92da0 285 tph_dur += UINT32_C(477 * 5); /* Gas measurement duration */
jsa1969 0:cef60cc92da0 286 tph_dur += UINT32_C(500); /* Get it to the closest whole number.*/
jsa1969 0:cef60cc92da0 287 tph_dur /= UINT32_C(1000); /* Convert to ms */
jsa1969 0:cef60cc92da0 288
jsa1969 0:cef60cc92da0 289 tph_dur += UINT32_C(1); /* Wake up duration of 1ms */
jsa1969 0:cef60cc92da0 290 /* The remaining time should be used for heating */
jsa1969 0:cef60cc92da0 291 _dev->gas_sett.heatr_dur = duration - (uint16_t) tph_dur;
jsa1969 0:cef60cc92da0 292 }
jsa1969 0:cef60cc92da0 293
jsa1969 0:cef60cc92da0 294 void Bme680::get_profile_dur(uint16_t *duration)
jsa1969 0:cef60cc92da0 295 {
jsa1969 0:cef60cc92da0 296 uint32_t tph_dur; /* Calculate in us */
jsa1969 0:cef60cc92da0 297 uint32_t meas_cycles;
jsa1969 0:cef60cc92da0 298 uint8_t os_to_meas_cycles[6] = {0, 1, 2, 4, 8, 16};
jsa1969 0:cef60cc92da0 299
jsa1969 0:cef60cc92da0 300 meas_cycles = os_to_meas_cycles[_dev->tph_sett.os_temp];
jsa1969 0:cef60cc92da0 301 meas_cycles += os_to_meas_cycles[_dev->tph_sett.os_pres];
jsa1969 0:cef60cc92da0 302 meas_cycles += os_to_meas_cycles[_dev->tph_sett.os_hum];
jsa1969 0:cef60cc92da0 303
jsa1969 0:cef60cc92da0 304 /* TPH measurement duration */
jsa1969 0:cef60cc92da0 305 tph_dur = meas_cycles * UINT32_C(1963);
jsa1969 0:cef60cc92da0 306 tph_dur += UINT32_C(477 * 4); /* TPH switching duration */
jsa1969 0:cef60cc92da0 307 tph_dur += UINT32_C(477 * 5); /* Gas measurement duration */
jsa1969 0:cef60cc92da0 308 tph_dur += UINT32_C(500); /* Get it to the closest whole number.*/
jsa1969 0:cef60cc92da0 309 tph_dur /= UINT32_C(1000); /* Convert to ms */
jsa1969 0:cef60cc92da0 310
jsa1969 0:cef60cc92da0 311 tph_dur += UINT32_C(1); /* Wake up duration of 1ms */
jsa1969 0:cef60cc92da0 312
jsa1969 0:cef60cc92da0 313 *duration = (uint16_t) tph_dur;
jsa1969 0:cef60cc92da0 314
jsa1969 0:cef60cc92da0 315 /* Get the gas duration only when the run gas is enabled */
jsa1969 0:cef60cc92da0 316 if (_dev->gas_sett.run_gas) {
jsa1969 0:cef60cc92da0 317 /* The remaining time should be used for heating */
jsa1969 0:cef60cc92da0 318 *duration += _dev->gas_sett.heatr_dur;
jsa1969 0:cef60cc92da0 319 }
jsa1969 0:cef60cc92da0 320 }
jsa1969 0:cef60cc92da0 321
jsa1969 0:cef60cc92da0 322 int Bme680::get_sensor_data(struct bme680_field_data *data)
jsa1969 0:cef60cc92da0 323 {
jsa1969 0:cef60cc92da0 324 int rslt = null_ptr_check();
jsa1969 0:cef60cc92da0 325 if (rslt!=BME680_OK) return rslt;
jsa1969 0:cef60cc92da0 326
jsa1969 0:cef60cc92da0 327 /* Reading the sensor data in forced mode only */
jsa1969 0:cef60cc92da0 328 rslt = read_field_data(data);
jsa1969 0:cef60cc92da0 329 if (rslt == BME680_OK) {
jsa1969 0:cef60cc92da0 330 if (data->status & BME680_NEW_DATA_MSK)
jsa1969 0:cef60cc92da0 331 _dev->new_fields = 1;
jsa1969 0:cef60cc92da0 332 else
jsa1969 0:cef60cc92da0 333 _dev->new_fields = 0;
jsa1969 0:cef60cc92da0 334 }
jsa1969 0:cef60cc92da0 335
jsa1969 0:cef60cc92da0 336 return rslt;
jsa1969 0:cef60cc92da0 337 }
jsa1969 0:cef60cc92da0 338
jsa1969 0:cef60cc92da0 339 int Bme680::read_field_data(struct bme680_field_data *data){
jsa1969 0:cef60cc92da0 340 int rslt = null_ptr_check();
jsa1969 0:cef60cc92da0 341 if (rslt!=BME680_OK) return rslt;
jsa1969 0:cef60cc92da0 342
jsa1969 0:cef60cc92da0 343 uint8_t buff[BME680_FIELD_LENGTH] = { 0 };
jsa1969 0:cef60cc92da0 344 uint8_t gas_range;
jsa1969 0:cef60cc92da0 345 uint32_t adc_temp;
jsa1969 0:cef60cc92da0 346 uint32_t adc_pres;
jsa1969 0:cef60cc92da0 347 uint16_t adc_hum;
jsa1969 0:cef60cc92da0 348 uint16_t adc_gas_res;
jsa1969 0:cef60cc92da0 349 uint8_t tries = 10;
jsa1969 0:cef60cc92da0 350
jsa1969 0:cef60cc92da0 351 do {
jsa1969 0:cef60cc92da0 352 if (rslt == BME680_OK) {
jsa1969 0:cef60cc92da0 353 rslt = get_regs(((uint8_t) (BME680_FIELD0_ADDR)), buff, (uint16_t) BME680_FIELD_LENGTH);
jsa1969 0:cef60cc92da0 354
jsa1969 0:cef60cc92da0 355 data->status = buff[0] & BME680_NEW_DATA_MSK;
jsa1969 0:cef60cc92da0 356 data->gas_index = buff[0] & BME680_GAS_INDEX_MSK;
jsa1969 0:cef60cc92da0 357 data->meas_index = buff[1];
jsa1969 0:cef60cc92da0 358
jsa1969 0:cef60cc92da0 359 /* read the raw data from the sensor */
jsa1969 0:cef60cc92da0 360 adc_pres = (uint32_t) (((uint32_t) buff[2] * 4096) | ((uint32_t) buff[3] * 16)
jsa1969 0:cef60cc92da0 361 | ((uint32_t) buff[4] / 16));
jsa1969 0:cef60cc92da0 362 adc_temp = (uint32_t) (((uint32_t) buff[5] * 4096) | ((uint32_t) buff[6] * 16)
jsa1969 0:cef60cc92da0 363 | ((uint32_t) buff[7] / 16));
jsa1969 0:cef60cc92da0 364 adc_hum = (uint16_t) (((uint32_t) buff[8] * 256) | (uint32_t) buff[9]);
jsa1969 0:cef60cc92da0 365 adc_gas_res = (uint16_t) ((uint32_t) buff[13] * 4 | (((uint32_t) buff[14]) / 64));
jsa1969 0:cef60cc92da0 366 gas_range = buff[14] & BME680_GAS_RANGE_MSK;
jsa1969 0:cef60cc92da0 367
jsa1969 0:cef60cc92da0 368 data->status |= buff[14] & BME680_GASM_VALID_MSK;
jsa1969 0:cef60cc92da0 369 data->status |= buff[14] & BME680_HEAT_STAB_MSK;
jsa1969 0:cef60cc92da0 370
jsa1969 0:cef60cc92da0 371 if (data->status & BME680_NEW_DATA_MSK) {
jsa1969 0:cef60cc92da0 372 data->temperature = calc_temperature(adc_temp);
jsa1969 0:cef60cc92da0 373 data->pressure = calc_pressure(adc_pres);
jsa1969 0:cef60cc92da0 374 data->humidity = calc_humidity(adc_hum);
jsa1969 0:cef60cc92da0 375 data->gas_resistance = calc_gas_resistance(adc_gas_res, gas_range);
jsa1969 0:cef60cc92da0 376 break;
jsa1969 0:cef60cc92da0 377 }
jsa1969 0:cef60cc92da0 378 /* Delay to poll the data */
jsa1969 0:cef60cc92da0 379 _i2cCallbacks->delay_ms(BME680_POLL_PERIOD_MS);
jsa1969 0:cef60cc92da0 380 }
jsa1969 0:cef60cc92da0 381 tries--;
jsa1969 0:cef60cc92da0 382 } while (tries);
jsa1969 0:cef60cc92da0 383
jsa1969 0:cef60cc92da0 384 if (!tries){
jsa1969 0:cef60cc92da0 385 rslt = BME680_W_NO_NEW_DATA;
jsa1969 0:cef60cc92da0 386 }
jsa1969 0:cef60cc92da0 387
jsa1969 0:cef60cc92da0 388 return rslt;
jsa1969 0:cef60cc92da0 389 }
jsa1969 0:cef60cc92da0 390
jsa1969 0:cef60cc92da0 391 int Bme680::get_sensor_mode(struct bme680_dev *dev)
jsa1969 0:cef60cc92da0 392 {
jsa1969 0:cef60cc92da0 393 int rslt = null_ptr_check();
jsa1969 0:cef60cc92da0 394 if (rslt!=BME680_OK) return rslt;
jsa1969 0:cef60cc92da0 395
jsa1969 0:cef60cc92da0 396 uint8_t mode;
jsa1969 0:cef60cc92da0 397
jsa1969 0:cef60cc92da0 398 rslt = get_regs(BME680_CONF_T_P_MODE_ADDR, &mode, 1);
jsa1969 0:cef60cc92da0 399 /* Masking the other register bit info*/
jsa1969 0:cef60cc92da0 400 _dev->power_mode = mode & BME680_MODE_MSK;
jsa1969 0:cef60cc92da0 401
jsa1969 0:cef60cc92da0 402 return rslt;
jsa1969 0:cef60cc92da0 403 }
jsa1969 0:cef60cc92da0 404
jsa1969 0:cef60cc92da0 405 int Bme680::set_sensor_mode()
jsa1969 0:cef60cc92da0 406 {
jsa1969 0:cef60cc92da0 407 int rslt = null_ptr_check();
jsa1969 0:cef60cc92da0 408 if (rslt!=BME680_OK) return rslt;
jsa1969 0:cef60cc92da0 409
jsa1969 0:cef60cc92da0 410 uint8_t tmp_pow_mode;
jsa1969 0:cef60cc92da0 411 uint8_t pow_mode = 0;
jsa1969 0:cef60cc92da0 412 uint8_t reg_addr = BME680_CONF_T_P_MODE_ADDR;
jsa1969 0:cef60cc92da0 413
jsa1969 0:cef60cc92da0 414 /* Call repeatedly until in sleep */
jsa1969 0:cef60cc92da0 415 do {
jsa1969 0:cef60cc92da0 416 rslt = get_regs(BME680_CONF_T_P_MODE_ADDR, &tmp_pow_mode, 1);
jsa1969 0:cef60cc92da0 417 if (rslt == BME680_OK) {
jsa1969 0:cef60cc92da0 418 /* Put to sleep before changing mode */
jsa1969 0:cef60cc92da0 419 pow_mode = (tmp_pow_mode & BME680_MODE_MSK);
jsa1969 0:cef60cc92da0 420
jsa1969 0:cef60cc92da0 421 if (pow_mode != BME680_SLEEP_MODE) {
jsa1969 0:cef60cc92da0 422 tmp_pow_mode = tmp_pow_mode & (~BME680_MODE_MSK); /* Set to sleep */
jsa1969 0:cef60cc92da0 423 rslt = set_regs(&reg_addr, &tmp_pow_mode, 1);
jsa1969 0:cef60cc92da0 424 _i2cCallbacks->delay_ms(BME680_POLL_PERIOD_MS);
jsa1969 0:cef60cc92da0 425 }
jsa1969 0:cef60cc92da0 426 }
jsa1969 0:cef60cc92da0 427 } while (pow_mode != BME680_SLEEP_MODE);
jsa1969 0:cef60cc92da0 428
jsa1969 0:cef60cc92da0 429 /* Already in sleep */
jsa1969 0:cef60cc92da0 430 if (_dev->power_mode != BME680_SLEEP_MODE) {
jsa1969 0:cef60cc92da0 431 tmp_pow_mode = (tmp_pow_mode & ~BME680_MODE_MSK) | (_dev->power_mode & BME680_MODE_MSK);
jsa1969 0:cef60cc92da0 432 if (rslt == BME680_OK) {
jsa1969 0:cef60cc92da0 433 rslt = set_regs(&reg_addr, &tmp_pow_mode, 1);
jsa1969 0:cef60cc92da0 434 }
jsa1969 0:cef60cc92da0 435 }
jsa1969 0:cef60cc92da0 436
jsa1969 0:cef60cc92da0 437 return rslt;
jsa1969 0:cef60cc92da0 438 }
jsa1969 0:cef60cc92da0 439
jsa1969 0:cef60cc92da0 440 int Bme680::set_gas_config()
jsa1969 0:cef60cc92da0 441 {
jsa1969 0:cef60cc92da0 442 int rslt = null_ptr_check();
jsa1969 0:cef60cc92da0 443 if (rslt!=BME680_OK) return rslt;
jsa1969 0:cef60cc92da0 444
jsa1969 0:cef60cc92da0 445 uint8_t reg_addr[2] = {0};
jsa1969 0:cef60cc92da0 446 uint8_t reg_data[2] = {0};
jsa1969 0:cef60cc92da0 447
jsa1969 0:cef60cc92da0 448 if (_dev->power_mode == BME680_FORCED_MODE) {
jsa1969 0:cef60cc92da0 449 reg_addr[0] = BME680_RES_HEAT0_ADDR;
jsa1969 0:cef60cc92da0 450 reg_data[0] = calc_heater_res(_dev->gas_sett.heatr_temp);
jsa1969 0:cef60cc92da0 451 reg_addr[1] = BME680_GAS_WAIT0_ADDR;
jsa1969 0:cef60cc92da0 452 reg_data[1] = calc_heater_dur(_dev->gas_sett.heatr_dur);
jsa1969 0:cef60cc92da0 453 _dev->gas_sett.nb_conv = 0;
jsa1969 0:cef60cc92da0 454 } else {
jsa1969 0:cef60cc92da0 455 rslt = BME680_W_DEFINE_PWR_MODE;
jsa1969 0:cef60cc92da0 456 }
jsa1969 0:cef60cc92da0 457
jsa1969 0:cef60cc92da0 458 if (rslt == BME680_OK) {
jsa1969 0:cef60cc92da0 459 rslt = set_regs(reg_addr, reg_data, 2);
jsa1969 0:cef60cc92da0 460 }
jsa1969 0:cef60cc92da0 461
jsa1969 0:cef60cc92da0 462 return rslt;
jsa1969 0:cef60cc92da0 463 }
jsa1969 0:cef60cc92da0 464
jsa1969 0:cef60cc92da0 465 uint8_t Bme680::calc_heater_dur(uint16_t dur)
jsa1969 0:cef60cc92da0 466 {
jsa1969 0:cef60cc92da0 467 uint8_t factor = 0;
jsa1969 0:cef60cc92da0 468 uint8_t durval;
jsa1969 0:cef60cc92da0 469
jsa1969 0:cef60cc92da0 470 if (dur >= 0xfc0) {
jsa1969 0:cef60cc92da0 471 durval = 0xff; /* Max duration*/
jsa1969 0:cef60cc92da0 472 } else {
jsa1969 0:cef60cc92da0 473 while (dur > 0x3F) {
jsa1969 0:cef60cc92da0 474 dur = dur / 4;
jsa1969 0:cef60cc92da0 475 factor += 1;
jsa1969 0:cef60cc92da0 476 }
jsa1969 0:cef60cc92da0 477 durval = (uint8_t) (dur + (factor * 64));
jsa1969 0:cef60cc92da0 478 }
jsa1969 0:cef60cc92da0 479
jsa1969 0:cef60cc92da0 480 return durval;
jsa1969 0:cef60cc92da0 481 }
jsa1969 0:cef60cc92da0 482
jsa1969 0:cef60cc92da0 483
jsa1969 0:cef60cc92da0 484 uint8_t Bme680::calc_heater_res(uint16_t temp)
jsa1969 0:cef60cc92da0 485 {
jsa1969 0:cef60cc92da0 486 uint8_t heatr_res;
jsa1969 0:cef60cc92da0 487 int32_t var1;
jsa1969 0:cef60cc92da0 488 int32_t var2;
jsa1969 0:cef60cc92da0 489 int32_t var3;
jsa1969 0:cef60cc92da0 490 int32_t var4;
jsa1969 0:cef60cc92da0 491 int32_t var5;
jsa1969 0:cef60cc92da0 492 int32_t heatr_res_x100;
jsa1969 0:cef60cc92da0 493
jsa1969 0:cef60cc92da0 494 if (temp > 400) {
jsa1969 0:cef60cc92da0 495 temp = 400;
jsa1969 0:cef60cc92da0 496 }
jsa1969 0:cef60cc92da0 497
jsa1969 0:cef60cc92da0 498 var1 = (((int32_t) _dev->amb_temp * _dev->calib.par_gh3) / 1000) * 256;
jsa1969 0:cef60cc92da0 499 var2 = (_dev->calib.par_gh1 + 784) * (((((_dev->calib.par_gh2 + 154009) * temp * 5) / 100) + 3276800) / 10);
jsa1969 0:cef60cc92da0 500 var3 = var1 + (var2 / 2);
jsa1969 0:cef60cc92da0 501 var4 = (var3 / (_dev->calib.res_heat_range + 4));
jsa1969 0:cef60cc92da0 502 var5 = (131 * _dev->calib.res_heat_val) + 65536;
jsa1969 0:cef60cc92da0 503 heatr_res_x100 = (int32_t) (((var4 / var5) - 250) * 34);
jsa1969 0:cef60cc92da0 504 heatr_res = (uint8_t) ((heatr_res_x100 + 50) / 100);
jsa1969 0:cef60cc92da0 505
jsa1969 0:cef60cc92da0 506 return heatr_res;
jsa1969 0:cef60cc92da0 507 }
jsa1969 0:cef60cc92da0 508
jsa1969 0:cef60cc92da0 509 int Bme680::boundary_check(uint8_t *value, uint8_t min, uint8_t max) {
jsa1969 0:cef60cc92da0 510 int rslt = BME680_OK;
jsa1969 0:cef60cc92da0 511
jsa1969 0:cef60cc92da0 512 if (value != NULL) {
jsa1969 0:cef60cc92da0 513 // Check if value is below minimum value
jsa1969 0:cef60cc92da0 514 if (*value < min) {
jsa1969 0:cef60cc92da0 515 // Auto correct the invalid value to minimum value
jsa1969 0:cef60cc92da0 516 *value = min;
jsa1969 0:cef60cc92da0 517 _dev->info_msg |= BME680_I_MIN_CORRECTION;
jsa1969 0:cef60cc92da0 518 }
jsa1969 0:cef60cc92da0 519 // Check if value is above maximum value
jsa1969 0:cef60cc92da0 520 if (*value > max) {
jsa1969 0:cef60cc92da0 521 // Auto correct the invalid value to maximum value
jsa1969 0:cef60cc92da0 522 *value = max;
jsa1969 0:cef60cc92da0 523 _dev->info_msg |= BME680_I_MAX_CORRECTION;
jsa1969 0:cef60cc92da0 524 }
jsa1969 0:cef60cc92da0 525 } else {
jsa1969 0:cef60cc92da0 526 rslt = BME680_E_NULL_PTR;
jsa1969 0:cef60cc92da0 527 }
jsa1969 0:cef60cc92da0 528
jsa1969 0:cef60cc92da0 529 return rslt;
jsa1969 0:cef60cc92da0 530 }
jsa1969 0:cef60cc92da0 531
jsa1969 0:cef60cc92da0 532 int Bme680::set_sensor_settings(uint16_t desired_settings)
jsa1969 0:cef60cc92da0 533 {
jsa1969 0:cef60cc92da0 534 int rslt = null_ptr_check();
jsa1969 0:cef60cc92da0 535 if (rslt!=BME680_OK) return rslt;
jsa1969 0:cef60cc92da0 536
jsa1969 0:cef60cc92da0 537 uint8_t reg_addr;
jsa1969 0:cef60cc92da0 538 uint8_t data = 0;
jsa1969 0:cef60cc92da0 539 uint8_t count = 0;
jsa1969 0:cef60cc92da0 540 uint8_t reg_array[BME680_REG_BUFFER_LENGTH] = { 0 };
jsa1969 0:cef60cc92da0 541 uint8_t data_array[BME680_REG_BUFFER_LENGTH] = { 0 };
jsa1969 0:cef60cc92da0 542 uint8_t intended_power_mode = _dev->power_mode; // Save intended power mode
jsa1969 0:cef60cc92da0 543
jsa1969 0:cef60cc92da0 544 // Check for null pointer in the device structure
jsa1969 0:cef60cc92da0 545
jsa1969 0:cef60cc92da0 546 if (desired_settings & BME680_GAS_MEAS_SEL) {
jsa1969 0:cef60cc92da0 547 rslt = set_gas_config();
jsa1969 0:cef60cc92da0 548 }
jsa1969 0:cef60cc92da0 549
jsa1969 0:cef60cc92da0 550 _dev->power_mode = BME680_SLEEP_MODE;
jsa1969 0:cef60cc92da0 551 if (rslt == BME680_OK) {
jsa1969 0:cef60cc92da0 552 rslt = set_sensor_mode();
jsa1969 0:cef60cc92da0 553 }
jsa1969 0:cef60cc92da0 554
jsa1969 0:cef60cc92da0 555 // Selecting the filter
jsa1969 0:cef60cc92da0 556 if (desired_settings & BME680_FILTER_SEL) {
jsa1969 0:cef60cc92da0 557 rslt = boundary_check(&(_dev->tph_sett.filter), BME680_FILTER_SIZE_0, BME680_FILTER_SIZE_127);
jsa1969 0:cef60cc92da0 558 reg_addr = BME680_CONF_ODR_FILT_ADDR;
jsa1969 0:cef60cc92da0 559
jsa1969 0:cef60cc92da0 560 if (rslt == BME680_OK) {
jsa1969 0:cef60cc92da0 561 rslt = get_regs(reg_addr, &data, 1);
jsa1969 0:cef60cc92da0 562 }
jsa1969 0:cef60cc92da0 563
jsa1969 0:cef60cc92da0 564 if (desired_settings & BME680_FILTER_SEL) {
jsa1969 0:cef60cc92da0 565 data = BME680_SET_BITS(data, BME680_FILTER, _dev->tph_sett.filter);
jsa1969 0:cef60cc92da0 566 }
jsa1969 0:cef60cc92da0 567
jsa1969 0:cef60cc92da0 568 reg_array[count] = reg_addr; // Append configuration
jsa1969 0:cef60cc92da0 569 data_array[count] = data;
jsa1969 0:cef60cc92da0 570 count++;
jsa1969 0:cef60cc92da0 571 }
jsa1969 0:cef60cc92da0 572
jsa1969 0:cef60cc92da0 573 // Selecting heater control for the sensor
jsa1969 0:cef60cc92da0 574 if (desired_settings & BME680_HCNTRL_SEL) {
jsa1969 0:cef60cc92da0 575 rslt = boundary_check(&(_dev->gas_sett.heatr_ctrl), BME680_ENABLE_HEATER,
jsa1969 0:cef60cc92da0 576 BME680_DISABLE_HEATER);
jsa1969 0:cef60cc92da0 577 reg_addr = BME680_CONF_HEAT_CTRL_ADDR;
jsa1969 0:cef60cc92da0 578
jsa1969 0:cef60cc92da0 579 if (rslt == BME680_OK){
jsa1969 0:cef60cc92da0 580 rslt = get_regs(reg_addr, &data, 1);
jsa1969 0:cef60cc92da0 581 }
jsa1969 0:cef60cc92da0 582
jsa1969 0:cef60cc92da0 583 data = BME680_SET_BITS_POS_0(data, BME680_HCTRL, _dev->gas_sett.heatr_ctrl);
jsa1969 0:cef60cc92da0 584
jsa1969 0:cef60cc92da0 585 reg_array[count] = reg_addr; // Append configuration
jsa1969 0:cef60cc92da0 586 data_array[count] = data;
jsa1969 0:cef60cc92da0 587 count++;
jsa1969 0:cef60cc92da0 588 }
jsa1969 0:cef60cc92da0 589
jsa1969 0:cef60cc92da0 590 // Selecting heater T,P oversampling for the sensor
jsa1969 0:cef60cc92da0 591 if (desired_settings & (BME680_OST_SEL | BME680_OSP_SEL)) {
jsa1969 0:cef60cc92da0 592 rslt = boundary_check(&(_dev->tph_sett.os_temp), BME680_OS_NONE, BME680_OS_16X);
jsa1969 0:cef60cc92da0 593 reg_addr = BME680_CONF_T_P_MODE_ADDR;
jsa1969 0:cef60cc92da0 594
jsa1969 0:cef60cc92da0 595 if (rslt == BME680_OK) {
jsa1969 0:cef60cc92da0 596 rslt = get_regs(reg_addr, &data, 1);
jsa1969 0:cef60cc92da0 597 }
jsa1969 0:cef60cc92da0 598
jsa1969 0:cef60cc92da0 599 if (desired_settings & BME680_OST_SEL) {
jsa1969 0:cef60cc92da0 600 data = BME680_SET_BITS(data, BME680_OST, _dev->tph_sett.os_temp);
jsa1969 0:cef60cc92da0 601 }
jsa1969 0:cef60cc92da0 602
jsa1969 0:cef60cc92da0 603 if (desired_settings & BME680_OSP_SEL) {
jsa1969 0:cef60cc92da0 604 data = BME680_SET_BITS(data, BME680_OSP, _dev->tph_sett.os_pres);
jsa1969 0:cef60cc92da0 605 }
jsa1969 0:cef60cc92da0 606
jsa1969 0:cef60cc92da0 607 reg_array[count] = reg_addr;
jsa1969 0:cef60cc92da0 608 data_array[count] = data;
jsa1969 0:cef60cc92da0 609 count++;
jsa1969 0:cef60cc92da0 610 }
jsa1969 0:cef60cc92da0 611
jsa1969 0:cef60cc92da0 612 // Selecting humidity oversampling for the sensor
jsa1969 0:cef60cc92da0 613 if (desired_settings & BME680_OSH_SEL) {
jsa1969 0:cef60cc92da0 614 rslt = boundary_check(&(_dev->tph_sett.os_hum), BME680_OS_NONE, BME680_OS_16X);
jsa1969 0:cef60cc92da0 615 reg_addr = BME680_CONF_OS_H_ADDR;
jsa1969 0:cef60cc92da0 616
jsa1969 0:cef60cc92da0 617 if (rslt == BME680_OK) {
jsa1969 0:cef60cc92da0 618 rslt = get_regs(reg_addr, &data, 1);
jsa1969 0:cef60cc92da0 619 }
jsa1969 0:cef60cc92da0 620
jsa1969 0:cef60cc92da0 621 data = BME680_SET_BITS_POS_0(data, BME680_OSH, _dev->tph_sett.os_hum);
jsa1969 0:cef60cc92da0 622
jsa1969 0:cef60cc92da0 623 reg_array[count] = reg_addr; // Append configuration
jsa1969 0:cef60cc92da0 624 data_array[count] = data;
jsa1969 0:cef60cc92da0 625 count++;
jsa1969 0:cef60cc92da0 626 }
jsa1969 0:cef60cc92da0 627
jsa1969 0:cef60cc92da0 628 // Selecting the runGas and NB conversion settings for the sensor
jsa1969 0:cef60cc92da0 629 if (desired_settings & (BME680_RUN_GAS_SEL | BME680_NBCONV_SEL)) {
jsa1969 0:cef60cc92da0 630 rslt = boundary_check(&(_dev->gas_sett.run_gas), BME680_RUN_GAS_DISABLE,
jsa1969 0:cef60cc92da0 631 BME680_RUN_GAS_ENABLE);
jsa1969 0:cef60cc92da0 632
jsa1969 0:cef60cc92da0 633 if (rslt == BME680_OK) {
jsa1969 0:cef60cc92da0 634 // Validate boundary conditions
jsa1969 0:cef60cc92da0 635 rslt = boundary_check(&(_dev->gas_sett.nb_conv), BME680_NBCONV_MIN,
jsa1969 0:cef60cc92da0 636 BME680_NBCONV_MAX);
jsa1969 0:cef60cc92da0 637 }
jsa1969 0:cef60cc92da0 638
jsa1969 0:cef60cc92da0 639 reg_addr = BME680_CONF_ODR_RUN_GAS_NBC_ADDR;
jsa1969 0:cef60cc92da0 640
jsa1969 0:cef60cc92da0 641 if (rslt == BME680_OK)
jsa1969 0:cef60cc92da0 642 rslt = get_regs(reg_addr, &data, 1);
jsa1969 0:cef60cc92da0 643
jsa1969 0:cef60cc92da0 644 if (desired_settings & BME680_RUN_GAS_SEL)
jsa1969 0:cef60cc92da0 645 data = BME680_SET_BITS(data, BME680_RUN_GAS, _dev->gas_sett.run_gas);
jsa1969 0:cef60cc92da0 646
jsa1969 0:cef60cc92da0 647 if (desired_settings & BME680_NBCONV_SEL)
jsa1969 0:cef60cc92da0 648 data = BME680_SET_BITS_POS_0(data, BME680_NBCONV, _dev->gas_sett.nb_conv);
jsa1969 0:cef60cc92da0 649
jsa1969 0:cef60cc92da0 650 reg_array[count] = reg_addr; // Append configuration
jsa1969 0:cef60cc92da0 651 data_array[count] = data;
jsa1969 0:cef60cc92da0 652 count++;
jsa1969 0:cef60cc92da0 653 }
jsa1969 0:cef60cc92da0 654
jsa1969 0:cef60cc92da0 655 if (rslt == BME680_OK)
jsa1969 0:cef60cc92da0 656 rslt = set_regs(reg_array, data_array, count);
jsa1969 0:cef60cc92da0 657
jsa1969 0:cef60cc92da0 658 // Restore previous intended power mode
jsa1969 0:cef60cc92da0 659 _dev->power_mode = intended_power_mode;
jsa1969 0:cef60cc92da0 660
jsa1969 0:cef60cc92da0 661 return rslt;
jsa1969 0:cef60cc92da0 662 }
jsa1969 0:cef60cc92da0 663
jsa1969 0:cef60cc92da0 664 int Bme680::get_sensor_settings(uint16_t desired_settings)
jsa1969 0:cef60cc92da0 665 {
jsa1969 0:cef60cc92da0 666 int rslt = null_ptr_check();
jsa1969 0:cef60cc92da0 667 if (rslt!=BME680_OK) return rslt;
jsa1969 0:cef60cc92da0 668
jsa1969 0:cef60cc92da0 669 /* starting address of the register array for burst read*/
jsa1969 0:cef60cc92da0 670 uint8_t reg_addr = BME680_CONF_HEAT_CTRL_ADDR;
jsa1969 0:cef60cc92da0 671 uint8_t data_array[BME680_REG_BUFFER_LENGTH] = { 0 };
jsa1969 0:cef60cc92da0 672
jsa1969 0:cef60cc92da0 673
jsa1969 0:cef60cc92da0 674 rslt = get_regs(reg_addr, data_array, BME680_REG_BUFFER_LENGTH);
jsa1969 0:cef60cc92da0 675
jsa1969 0:cef60cc92da0 676 if (rslt == BME680_OK) {
jsa1969 0:cef60cc92da0 677 if (desired_settings & BME680_GAS_MEAS_SEL)
jsa1969 0:cef60cc92da0 678 rslt = get_gas_config();
jsa1969 0:cef60cc92da0 679
jsa1969 0:cef60cc92da0 680 /* get the T,P,H ,Filter,ODR settings here */
jsa1969 0:cef60cc92da0 681 if (desired_settings & BME680_FILTER_SEL)
jsa1969 0:cef60cc92da0 682 _dev->tph_sett.filter = BME680_GET_BITS(data_array[BME680_REG_FILTER_INDEX],
jsa1969 0:cef60cc92da0 683 BME680_FILTER);
jsa1969 0:cef60cc92da0 684
jsa1969 0:cef60cc92da0 685 if (desired_settings & (BME680_OST_SEL | BME680_OSP_SEL)) {
jsa1969 0:cef60cc92da0 686 _dev->tph_sett.os_temp = BME680_GET_BITS(data_array[BME680_REG_TEMP_INDEX], BME680_OST);
jsa1969 0:cef60cc92da0 687 _dev->tph_sett.os_pres = BME680_GET_BITS(data_array[BME680_REG_PRES_INDEX], BME680_OSP);
jsa1969 0:cef60cc92da0 688 }
jsa1969 0:cef60cc92da0 689
jsa1969 0:cef60cc92da0 690 if (desired_settings & BME680_OSH_SEL)
jsa1969 0:cef60cc92da0 691 _dev->tph_sett.os_hum = BME680_GET_BITS_POS_0(data_array[BME680_REG_HUM_INDEX],
jsa1969 0:cef60cc92da0 692 BME680_OSH);
jsa1969 0:cef60cc92da0 693
jsa1969 0:cef60cc92da0 694 /* get the gas related settings */
jsa1969 0:cef60cc92da0 695 if (desired_settings & BME680_HCNTRL_SEL)
jsa1969 0:cef60cc92da0 696 _dev->gas_sett.heatr_ctrl = BME680_GET_BITS_POS_0(data_array[BME680_REG_HCTRL_INDEX],
jsa1969 0:cef60cc92da0 697 BME680_HCTRL);
jsa1969 0:cef60cc92da0 698
jsa1969 0:cef60cc92da0 699 if (desired_settings & (BME680_RUN_GAS_SEL | BME680_NBCONV_SEL)) {
jsa1969 0:cef60cc92da0 700 _dev->gas_sett.nb_conv = BME680_GET_BITS_POS_0(data_array[BME680_REG_NBCONV_INDEX],
jsa1969 0:cef60cc92da0 701 BME680_NBCONV);
jsa1969 0:cef60cc92da0 702 _dev->gas_sett.run_gas = BME680_GET_BITS(data_array[BME680_REG_RUN_GAS_INDEX],
jsa1969 0:cef60cc92da0 703 BME680_RUN_GAS);
jsa1969 0:cef60cc92da0 704 }
jsa1969 0:cef60cc92da0 705 }
jsa1969 0:cef60cc92da0 706
jsa1969 0:cef60cc92da0 707 return rslt;
jsa1969 0:cef60cc92da0 708 }
jsa1969 0:cef60cc92da0 709
jsa1969 0:cef60cc92da0 710 int Bme680::get_gas_config()
jsa1969 0:cef60cc92da0 711 {
jsa1969 0:cef60cc92da0 712 int rslt = null_ptr_check();
jsa1969 0:cef60cc92da0 713 if (rslt!=BME680_OK) return rslt;
jsa1969 0:cef60cc92da0 714
jsa1969 0:cef60cc92da0 715 /* starting address of the register array for burst read*/
jsa1969 0:cef60cc92da0 716 uint8_t reg_addr1 = BME680_ADDR_SENS_CONF_START;
jsa1969 0:cef60cc92da0 717 uint8_t reg_addr2 = BME680_ADDR_GAS_CONF_START;
jsa1969 0:cef60cc92da0 718 uint8_t reg_data = 0;
jsa1969 0:cef60cc92da0 719
jsa1969 0:cef60cc92da0 720 if (rslt == BME680_OK) {
jsa1969 0:cef60cc92da0 721 rslt = get_regs(reg_addr1, &reg_data, 1);
jsa1969 0:cef60cc92da0 722 if (rslt == BME680_OK) {
jsa1969 0:cef60cc92da0 723 _dev->gas_sett.heatr_temp = reg_data;
jsa1969 0:cef60cc92da0 724 rslt = get_regs(reg_addr2, &reg_data, 1);
jsa1969 0:cef60cc92da0 725 if (rslt == BME680_OK) {
jsa1969 0:cef60cc92da0 726 /* Heating duration register value */
jsa1969 0:cef60cc92da0 727 _dev->gas_sett.heatr_dur = reg_data;
jsa1969 0:cef60cc92da0 728 }
jsa1969 0:cef60cc92da0 729 }
jsa1969 0:cef60cc92da0 730 }
jsa1969 0:cef60cc92da0 731
jsa1969 0:cef60cc92da0 732 return rslt;
jsa1969 0:cef60cc92da0 733 }
jsa1969 0:cef60cc92da0 734
jsa1969 0:cef60cc92da0 735 int16_t Bme680::calc_temperature(uint32_t temp_adc)
jsa1969 0:cef60cc92da0 736 {
jsa1969 0:cef60cc92da0 737 int64_t var1;
jsa1969 0:cef60cc92da0 738 int64_t var2;
jsa1969 0:cef60cc92da0 739 int64_t var3;
jsa1969 0:cef60cc92da0 740 int16_t calc_temp;
jsa1969 0:cef60cc92da0 741
jsa1969 0:cef60cc92da0 742 var1 = ((int32_t) temp_adc >> 3) - ((int32_t) _dev->calib.par_t1 << 1);
jsa1969 0:cef60cc92da0 743 var2 = (var1 * (int32_t) _dev->calib.par_t2) >> 11;
jsa1969 0:cef60cc92da0 744 var3 = ((var1 >> 1) * (var1 >> 1)) >> 12;
jsa1969 0:cef60cc92da0 745 var3 = ((var3) * ((int32_t) _dev->calib.par_t3 << 4)) >> 14;
jsa1969 0:cef60cc92da0 746 _dev->calib.t_fine = (int32_t) (var2 + var3);
jsa1969 0:cef60cc92da0 747 calc_temp = (int16_t) (((_dev->calib.t_fine * 5) + 128) >> 8);
jsa1969 0:cef60cc92da0 748
jsa1969 0:cef60cc92da0 749 return calc_temp;
jsa1969 0:cef60cc92da0 750 }
jsa1969 0:cef60cc92da0 751
jsa1969 0:cef60cc92da0 752 uint32_t Bme680::calc_pressure(uint32_t pres_adc)
jsa1969 0:cef60cc92da0 753 {
jsa1969 0:cef60cc92da0 754 int32_t var1 = 0;
jsa1969 0:cef60cc92da0 755 int32_t var2 = 0;
jsa1969 0:cef60cc92da0 756 int32_t var3 = 0;
jsa1969 0:cef60cc92da0 757 int32_t pressure_comp = 0;
jsa1969 0:cef60cc92da0 758
jsa1969 0:cef60cc92da0 759 var1 = (((int32_t)_dev->calib.t_fine) >> 1) - 64000;
jsa1969 0:cef60cc92da0 760 var2 = ((((var1 >> 2) * (var1 >> 2)) >> 11) *
jsa1969 0:cef60cc92da0 761 (int32_t)_dev->calib.par_p6) >> 2;
jsa1969 0:cef60cc92da0 762 var2 = var2 + ((var1 * (int32_t)_dev->calib.par_p5) << 1);
jsa1969 0:cef60cc92da0 763 var2 = (var2 >> 2) + ((int32_t)_dev->calib.par_p4 << 16);
jsa1969 0:cef60cc92da0 764 var1 = (((((var1 >> 2) * (var1 >> 2)) >> 13) *
jsa1969 0:cef60cc92da0 765 ((int32_t)_dev->calib.par_p3 << 5)) >> 3) +
jsa1969 0:cef60cc92da0 766 (((int32_t)_dev->calib.par_p2 * var1) >> 1);
jsa1969 0:cef60cc92da0 767 var1 = var1 >> 18;
jsa1969 0:cef60cc92da0 768 var1 = ((32768 + var1) * (int32_t)_dev->calib.par_p1) >> 15;
jsa1969 0:cef60cc92da0 769 pressure_comp = 1048576 - pres_adc;
jsa1969 0:cef60cc92da0 770 pressure_comp = (int32_t)((pressure_comp - (var2 >> 12)) * ((uint32_t)3125));
jsa1969 0:cef60cc92da0 771 if (pressure_comp >= BME680_MAX_OVERFLOW_VAL)
jsa1969 0:cef60cc92da0 772 pressure_comp = ((pressure_comp / (uint32_t)var1) << 1);
jsa1969 0:cef60cc92da0 773 else
jsa1969 0:cef60cc92da0 774 pressure_comp = ((pressure_comp << 1) / (uint32_t)var1);
jsa1969 0:cef60cc92da0 775 var1 = ((int32_t)_dev->calib.par_p9 * (int32_t)(((pressure_comp >> 3) *
jsa1969 0:cef60cc92da0 776 (pressure_comp >> 3)) >> 13)) >> 12;
jsa1969 0:cef60cc92da0 777 var2 = ((int32_t)(pressure_comp >> 2) *
jsa1969 0:cef60cc92da0 778 (int32_t)_dev->calib.par_p8) >> 13;
jsa1969 0:cef60cc92da0 779 var3 = ((int32_t)(pressure_comp >> 8) * (int32_t)(pressure_comp >> 8) *
jsa1969 0:cef60cc92da0 780 (int32_t)(pressure_comp >> 8) *
jsa1969 0:cef60cc92da0 781 (int32_t)_dev->calib.par_p10) >> 17;
jsa1969 0:cef60cc92da0 782
jsa1969 0:cef60cc92da0 783 pressure_comp = (int32_t)(pressure_comp) + ((var1 + var2 + var3 +
jsa1969 0:cef60cc92da0 784 ((int32_t)_dev->calib.par_p7 << 7)) >> 4);
jsa1969 0:cef60cc92da0 785
jsa1969 0:cef60cc92da0 786 return (uint32_t)pressure_comp;
jsa1969 0:cef60cc92da0 787
jsa1969 0:cef60cc92da0 788 }
jsa1969 0:cef60cc92da0 789
jsa1969 0:cef60cc92da0 790 uint32_t Bme680::calc_humidity(uint16_t hum_adc)
jsa1969 0:cef60cc92da0 791 {
jsa1969 0:cef60cc92da0 792 int32_t var1;
jsa1969 0:cef60cc92da0 793 int32_t var2;
jsa1969 0:cef60cc92da0 794 int32_t var3;
jsa1969 0:cef60cc92da0 795 int32_t var4;
jsa1969 0:cef60cc92da0 796 int32_t var5;
jsa1969 0:cef60cc92da0 797 int32_t var6;
jsa1969 0:cef60cc92da0 798 int32_t temp_scaled;
jsa1969 0:cef60cc92da0 799 int32_t calc_hum;
jsa1969 0:cef60cc92da0 800
jsa1969 0:cef60cc92da0 801 temp_scaled = (((int32_t) _dev->calib.t_fine * 5) + 128) >> 8;
jsa1969 0:cef60cc92da0 802 var1 = (int32_t) (hum_adc - ((int32_t) ((int32_t) _dev->calib.par_h1 * 16)))
jsa1969 0:cef60cc92da0 803 - (((temp_scaled * (int32_t) _dev->calib.par_h3) / ((int32_t) 100)) >> 1);
jsa1969 0:cef60cc92da0 804 var2 = ((int32_t) _dev->calib.par_h2
jsa1969 0:cef60cc92da0 805 * (((temp_scaled * (int32_t) _dev->calib.par_h4) / ((int32_t) 100))
jsa1969 0:cef60cc92da0 806 + (((temp_scaled * ((temp_scaled * (int32_t) _dev->calib.par_h5) / ((int32_t) 100))) >> 6)
jsa1969 0:cef60cc92da0 807 / ((int32_t) 100)) + (int32_t) (1 << 14))) >> 10;
jsa1969 0:cef60cc92da0 808 var3 = var1 * var2;
jsa1969 0:cef60cc92da0 809 var4 = (int32_t) _dev->calib.par_h6 << 7;
jsa1969 0:cef60cc92da0 810 var4 = ((var4) + ((temp_scaled * (int32_t) _dev->calib.par_h7) / ((int32_t) 100))) >> 4;
jsa1969 0:cef60cc92da0 811 var5 = ((var3 >> 14) * (var3 >> 14)) >> 10;
jsa1969 0:cef60cc92da0 812 var6 = (var4 * var5) >> 1;
jsa1969 0:cef60cc92da0 813 calc_hum = (((var3 + var6) >> 10) * ((int32_t) 1000)) >> 12;
jsa1969 0:cef60cc92da0 814
jsa1969 0:cef60cc92da0 815 if (calc_hum > 100000) /* Cap at 100%rH */
jsa1969 0:cef60cc92da0 816 calc_hum = 100000;
jsa1969 0:cef60cc92da0 817 else if (calc_hum < 0)
jsa1969 0:cef60cc92da0 818 calc_hum = 0;
jsa1969 0:cef60cc92da0 819
jsa1969 0:cef60cc92da0 820 return (uint32_t) calc_hum;
jsa1969 0:cef60cc92da0 821 }
jsa1969 0:cef60cc92da0 822
jsa1969 0:cef60cc92da0 823 uint32_t Bme680::calc_gas_resistance(uint16_t gas_res_adc, uint8_t gas_range)
jsa1969 0:cef60cc92da0 824 {
jsa1969 0:cef60cc92da0 825 int64_t var1;
jsa1969 0:cef60cc92da0 826 uint64_t var2;
jsa1969 0:cef60cc92da0 827 int64_t var3;
jsa1969 0:cef60cc92da0 828 uint32_t calc_gas_res;
jsa1969 0:cef60cc92da0 829 /**Look up table 1 for the possible gas range values */
jsa1969 0:cef60cc92da0 830 uint32_t lookupTable1[16] = { UINT32_C(2147483647), UINT32_C(2147483647), UINT32_C(2147483647), UINT32_C(2147483647),
jsa1969 0:cef60cc92da0 831 UINT32_C(2147483647), UINT32_C(2126008810), UINT32_C(2147483647), UINT32_C(2130303777),
jsa1969 0:cef60cc92da0 832 UINT32_C(2147483647), UINT32_C(2147483647), UINT32_C(2143188679), UINT32_C(2136746228),
jsa1969 0:cef60cc92da0 833 UINT32_C(2147483647), UINT32_C(2126008810), UINT32_C(2147483647), UINT32_C(2147483647) };
jsa1969 0:cef60cc92da0 834 /**Look up table 2 for the possible gas range values */
jsa1969 0:cef60cc92da0 835 uint32_t lookupTable2[16] = { UINT32_C(4096000000), UINT32_C(2048000000), UINT32_C(1024000000), UINT32_C(512000000),
jsa1969 0:cef60cc92da0 836 UINT32_C(255744255), UINT32_C(127110228), UINT32_C(64000000), UINT32_C(32258064), UINT32_C(16016016),
jsa1969 0:cef60cc92da0 837 UINT32_C(8000000), UINT32_C(4000000), UINT32_C(2000000), UINT32_C(1000000), UINT32_C(500000),
jsa1969 0:cef60cc92da0 838 UINT32_C(250000), UINT32_C(125000) };
jsa1969 0:cef60cc92da0 839
jsa1969 0:cef60cc92da0 840 var1 = (int64_t) ((1340 + (5 * (int64_t) _dev->calib.range_sw_err)) *
jsa1969 0:cef60cc92da0 841 ((int64_t) lookupTable1[gas_range])) >> 16;
jsa1969 0:cef60cc92da0 842 var2 = (((int64_t) ((int64_t) gas_res_adc << 15) - (int64_t) (16777216)) + var1);
jsa1969 0:cef60cc92da0 843 var3 = (((int64_t) lookupTable2[gas_range] * (int64_t) var1) >> 9);
jsa1969 0:cef60cc92da0 844 calc_gas_res = (uint32_t) ((var3 + ((int64_t) var2 >> 1)) / (int64_t) var2);
jsa1969 0:cef60cc92da0 845
jsa1969 0:cef60cc92da0 846 return calc_gas_res;
jsa1969 0:cef60cc92da0 847 }
jsa1969 0:cef60cc92da0 848
jsa1969 0:cef60cc92da0 849