#include /* Common */ #include "sensors_common.h" /* Private */ #include "dht_bme280.h" #define IMS_BME280_REG_DIG_T1_L (0x88U) #define IMS_BME280_REG_DIG_T1_H (0x89U) #define IMS_BME280_REG_DIG_T2_L (0x8AU) #define IMS_BME280_REG_DIG_T2_H (0x8BU) #define IMS_BME280_REG_DIG_T3_L (0x8CU) #define IMS_BME280_REG_DIG_T3_H (0x8DU) #define IMS_BME280_REG_DIG_P1_L (0x8EU) #define IMS_BME280_REG_DIG_P1_H (0x8FU) #define IMS_BME280_REG_DIG_P2_L (0x90U) #define IMS_BME280_REG_DIG_P2_H (0x91U) #define IMS_BME280_REG_DIG_P3_L (0x92U) #define IMS_BME280_REG_DIG_P3_H (0x93U) #define IMS_BME280_REG_DIG_P4_L (0x94U) #define IMS_BME280_REG_DIG_P4_H (0x95U) #define IMS_BME280_REG_DIG_P5_L (0x96U) #define IMS_BME280_REG_DIG_P5_H (0x97U) #define IMS_BME280_REG_DIG_P6_L (0x98U) #define IMS_BME280_REG_DIG_P6_H (0x99U) #define IMS_BME280_REG_DIG_P7_L (0x9AU) #define IMS_BME280_REG_DIG_P7_H (0x9BU) #define IMS_BME280_REG_DIG_P8_L (0x9CU) #define IMS_BME280_REG_DIG_P8_H (0x9DU) #define IMS_BME280_REG_DIG_P9_L (0x9EU) #define IMS_BME280_REG_DIG_P9_H (0x9FU) #define IMS_BME280_REG_DIG_H1 (0xA1U) #define IMS_BME280_REG_DIG_H2_L (0xE1U) #define IMS_BME280_REG_DIG_H2_H (0xE2U) #define IMS_BME280_REG_DIG_H3 (0xE3U) #define IMS_BME280_REG_DIG_H4_H (0xE4U) #define IMS_BME280_REG_DIG_H4_L (0xE5U) #define IMS_BME280_REG_DIG_H5_L (0xE5U) #define IMS_BME280_REG_DIG_H5_H (0xE6U) #define IMS_BME280_REG_DIG_H6 (0xE7U) #define IMS_BME280_REG_RESET (0xE0U) #define IMS_BME280_REG_CTRL_HUM (0xF2U) #define IMS_BME280_REG_STATUS (0xF3U) #define IMS_BME280_REG_CTRL_MEAS (0xF4U) #define IMS_BME280_REG_CONFIG (0xF5U) #define IMS_BME280_REG_PRESS_MSB (0xF7U) #define IMS_BME280_REG_STATUS_MEASURING_Pos (3U) #define IMS_BME280_REG_STATUS_MEASURING_Msk (1U << IMS_BME280_REG_STATUS_MEASURING_Pos) #define IMS_BME280_REG_CTRL_MEAS_MODE_Pos (0U) #define IMS_BME280_REG_CTRL_MEAS_MODE_Msk (3U << IMS_BME280_REG_CTRL_MEAS_MODE_Pos) #define IMS_BME280_CONST_RESET_MAGIC (0xB6U) #define IMS_BME280_FORCED_TIMEOUT_MS 100 #define IMS_BME280_CONCAT_BYTES(msb, lsb) (((uint16_t)msb << 8) | (uint16_t)lsb) static const ims_bme280_config_t ims_bme280_presets[] = { [IMS_BME280_PRESET_WEATHER] = { .mode = IMS_BME280_MODE_FORCED, .osrs_t = IMS_BME280_OSRS_1, .osrs_p = IMS_BME280_OSRS_1, .osrs_h = IMS_BME280_OSRS_1, .filter = IMS_BME280_FILTER_OFF, }, [IMS_BME280_PRESET_HUMIDITY] = { .mode = IMS_BME280_MODE_FORCED, .osrs_t = IMS_BME280_OSRS_1, .osrs_p = IMS_BME280_OSRS_SKIP, .osrs_h = IMS_BME280_OSRS_1, .filter = IMS_BME280_FILTER_OFF, }, [IMS_BME280_PRESET_INDOOR_NAV] = { .mode = IMS_BME280_MODE_NORMAL, .osrs_t = IMS_BME280_OSRS_2, .osrs_p = IMS_BME280_OSRS_16, .osrs_h = IMS_BME280_OSRS_1, .t_sb = IMS_BME280_STANDBY_TIME_0_5_MS, .filter = IMS_BME280_FILTER_16, }, [IMS_BME280_PRESET_GAMING] = { .mode = IMS_BME280_MODE_NORMAL, .osrs_t = IMS_BME280_OSRS_1, .osrs_p = IMS_BME280_OSRS_4, .osrs_h = IMS_BME280_OSRS_SKIP, .t_sb = IMS_BME280_STANDBY_TIME_0_5_MS, .filter = IMS_BME280_FILTER_4, }, }; static ims_ret_t ims_bme280_reset(ims_bme280_t *bme); static ims_ret_t ims_bme280_read_trim_data(ims_bme280_t *bme); static ims_ret_t ims_bme280_set_mode(ims_bme280_t *bme, ims_bme280_mode_t mode); static ims_ret_t ims_bme280_get_mode(ims_bme280_t *bme, ims_bme280_mode_t *mode); static ims_ret_t ims_bme280_wait_measure_complete(ims_bme280_t *bme, uint32_t timeout_ms); static ims_ret_t ims_bme280_read_raw_data(ims_bme280_t *bme, uint32_t *raw_t, uint32_t *raw_p, uint32_t *raw_h); static ims_ret_t ims_bme280_read_register(ims_bme280_t *bme, uint8_t reg, uint8_t *data, uint16_t len); static ims_ret_t ims_bme280_write_register(ims_bme280_t *bme, uint8_t reg, uint8_t data); #ifdef IMS_CFG_DHT_BME280_ENABLE_FLOAT static double ims_bme280_compensate_T_double(ims_bme280_t *bme, int32_t adc_T); static double ims_bme280_compensate_P_double(ims_bme280_t *bme, int32_t adc_P); static double ims_bme280_compensate_H_double(ims_bme280_t *bme, int32_t adc_H); #else static int32_t ims_bme280_compensate_T_int32(ims_bme280_t *bme, int32_t adc_T); static uint32_t ims_bme280_compensate_P_int64(ims_bme280_t *bme, int32_t adc_P); static uint32_t ims_bme280_compensate_H_int32(ims_bme280_t *bme, int32_t adc_H); #endif ims_ret_t ims_bme280_init(ims_bme280_t *bme) { if (!bme) return IMS_FAIL; if (ims_bme280_reset(bme) == IMS_FAIL) return IMS_FAIL; bme->cb.delay(bme->pdev, 100); if (ims_bme280_read_trim_data(bme) == IMS_FAIL) return IMS_FAIL; return IMS_SUCCESS; } ims_ret_t ims_bme280_preset_config(ims_bme280_config_t *config, ims_bme280_mode_preset_t preset) { if (preset >= IMS_BME280_PRESET_END) { return IMS_FAIL; } memcpy(config, &ims_bme280_presets[preset], sizeof(ims_bme280_config_t)); return IMS_SUCCESS; } ims_ret_t ims_bme280_config(ims_bme280_t *bme, ims_bme280_config_t *config) { ims_ret_t ret; uint8_t reg_config = (config->filter << 0x02) | (config->t_sb << 0x05); uint8_t reg_ctrl_measure = (uint8_t)((config->osrs_t << 0x05) | (config->osrs_p << 0x02) | config->mode); uint8_t reg_ctrl_hum = config->osrs_h; ims_bme280_mode_t mode; ret = ims_bme280_get_mode(bme, &mode); if (ret != IMS_SUCCESS) return ret; if (mode != IMS_BME280_MODE_SLEEP) { ret = ims_bme280_set_mode(bme, IMS_BME280_MODE_SLEEP); if (ret != IMS_SUCCESS) return ret; } ret = ims_bme280_write_register(bme, IMS_BME280_REG_CONFIG, reg_config); if (ret != IMS_SUCCESS) return ret; ret = ims_bme280_write_register(bme, IMS_BME280_REG_CTRL_HUM, reg_ctrl_hum); if (ret != IMS_SUCCESS) return ret; ret = ims_bme280_write_register(bme, IMS_BME280_REG_CTRL_MEAS, reg_ctrl_measure); return ret; } ims_ret_t ims_bme280_read(ims_bme280_t *bme, ims_bme280_result_t *result) { ims_ret_t ret; uint32_t raw_P = 0x00; uint32_t raw_T = 0x00; uint32_t raw_H = 0x00; ret = ims_bme280_read_raw_data(bme, &raw_T, &raw_P, &raw_H); if (ret != IMS_SUCCESS) { return ret; } #if IMS_CFG_DHT_BME280_ENABLE_FLOAT result->temperature = ims_bme280_compensate_T_double(bme, (int32_t)raw_T); result->pressure = ims_bme280_compensate_P_double(bme, (int32_t)raw_P); result->humidity = ims_bme280_compensate_H_double(bme, (int32_t)raw_H); #else result->temperature = ims_bme280_compensate_T_int32(bme, (int32_t)raw_T); result->pressure = ims_bme280_compensate_P_int64(bme, (int32_t)raw_P); result->humidity = ims_bme280_compensate_H_int32(bme, (int32_t)raw_H); #endif return IMS_SUCCESS; } /** * Force a new result to be sampled, or wait for a new result be available if the sensor is in NORMAL mode. * @param bme * @param result * @return */ ims_ret_t ims_bme280_read_forced(ims_bme280_t *bme, ims_bme280_result_t *result) { ims_ret_t ret; uint32_t raw_P = 0x00; uint32_t raw_T = 0x00; uint32_t raw_H = 0x00; ims_bme280_mode_t mode; ret = ims_bme280_get_mode(bme, &mode); if (ret != IMS_SUCCESS) return ret; /* * If the sensor is in SLEEP mode, start a forced measurement; * if the sensor is measuring or in NORMAL mode, wait for a new result to be sampled. */ if (mode == IMS_BME280_MODE_SLEEP) { ret = ims_bme280_set_mode(bme, IMS_BME280_MODE_FORCED); if (ret != IMS_SUCCESS) return ret; } ret = ims_bme280_wait_measure_complete(bme, IMS_BME280_FORCED_TIMEOUT_MS); if (ret != IMS_SUCCESS) { return ret; } ret = ims_bme280_read_raw_data(bme, &raw_T, &raw_P, &raw_H); if (ret != IMS_SUCCESS) { return ret; } #if IMS_CFG_DHT_BME280_ENABLE_FLOAT result->temperature = ims_bme280_compensate_T_double(bme, (int32_t)raw_T); result->pressure = ims_bme280_compensate_P_double(bme, (int32_t)raw_P); result->humidity = ims_bme280_compensate_H_double(bme, (int32_t)raw_H); #else result->temperature = ims_bme280_compensate_T_int32(bme, (int32_t)raw_T); result->pressure = ims_bme280_compensate_P_int64(bme, (int32_t)raw_P); result->humidity = ims_bme280_compensate_H_int32(bme, (int32_t)raw_H); #endif return IMS_SUCCESS; } static ims_ret_t ims_bme280_reset(ims_bme280_t *bme) { return ims_bme280_write_register(bme, IMS_BME280_REG_RESET, IMS_BME280_CONST_RESET_MAGIC); } static ims_ret_t ims_bme280_read_trim_data(ims_bme280_t *bme) { ims_ret_t ret; uint8_t rx_buf[2]; ret = ims_bme280_read_register(bme, IMS_BME280_REG_DIG_T1_L, rx_buf, 0x02); // T1 if (ret == IMS_FAIL) return ret; bme->trim.dig_T1 = IMS_BME280_CONCAT_BYTES(rx_buf[1], rx_buf[0]); ret = ims_bme280_read_register(bme, IMS_BME280_REG_DIG_T2_L, rx_buf, 0x02); // T2 if (ret == IMS_FAIL) return ret; bme->trim.dig_T2 = (int16_t)IMS_BME280_CONCAT_BYTES(rx_buf[1], rx_buf[0]); ret = ims_bme280_read_register(bme, IMS_BME280_REG_DIG_T3_L, rx_buf, 0x02); // T3 if (ret == IMS_FAIL) return ret; bme->trim.dig_T3 = (int16_t)IMS_BME280_CONCAT_BYTES(rx_buf[1], rx_buf[0]); ret = ims_bme280_read_register(bme, IMS_BME280_REG_DIG_P1_L, rx_buf, 0x02); // P1 if (ret == IMS_FAIL) return ret; bme->trim.dig_P1 = IMS_BME280_CONCAT_BYTES(rx_buf[1], rx_buf[0]); ret = ims_bme280_read_register(bme, IMS_BME280_REG_DIG_P2_L, rx_buf, 0x02); // P2 if (ret == IMS_FAIL) return ret; bme->trim.dig_P2 = (int16_t)IMS_BME280_CONCAT_BYTES(rx_buf[1], rx_buf[0]); ret = ims_bme280_read_register(bme, IMS_BME280_REG_DIG_P3_L, rx_buf, 0x02); // P3 if (ret == IMS_FAIL) return ret; bme->trim.dig_P3 = (int16_t)IMS_BME280_CONCAT_BYTES(rx_buf[1], rx_buf[0]); ret = ims_bme280_read_register(bme, IMS_BME280_REG_DIG_P4_L, rx_buf, 0x02); // P4 if (ret == IMS_FAIL) return ret; bme->trim.dig_P4 = (int16_t)IMS_BME280_CONCAT_BYTES(rx_buf[1], rx_buf[0]); ret = ims_bme280_read_register(bme, IMS_BME280_REG_DIG_P5_L, rx_buf, 0x02); // P5 if (ret == IMS_FAIL) return ret; bme->trim.dig_P5 = (int16_t)IMS_BME280_CONCAT_BYTES(rx_buf[1], rx_buf[0]); ret = ims_bme280_read_register(bme, IMS_BME280_REG_DIG_P6_L, rx_buf, 0x02); // P6 if (ret == IMS_FAIL) return ret; bme->trim.dig_P6 = (int16_t)IMS_BME280_CONCAT_BYTES(rx_buf[1], rx_buf[0]); ret = ims_bme280_read_register(bme, IMS_BME280_REG_DIG_P7_L, rx_buf, 0x02); // P7 if (ret == IMS_FAIL) return ret; bme->trim.dig_P7 = (int16_t)IMS_BME280_CONCAT_BYTES(rx_buf[1], rx_buf[0]); ret = ims_bme280_read_register(bme, IMS_BME280_REG_DIG_P8_L, rx_buf, 0x02); // P8 if (ret == IMS_FAIL) return ret; bme->trim.dig_P8 = (int16_t)IMS_BME280_CONCAT_BYTES(rx_buf[1], rx_buf[0]); ret = ims_bme280_read_register(bme, IMS_BME280_REG_DIG_P9_L, rx_buf, 0x02); // P9 if (ret == IMS_FAIL) return ret; bme->trim.dig_P9 = (int16_t)IMS_BME280_CONCAT_BYTES(rx_buf[1], rx_buf[0]); ret = ims_bme280_read_register(bme, IMS_BME280_REG_DIG_H1, rx_buf, 0x01); // H1 if (ret == IMS_FAIL) return ret; bme->trim.dig_H1 = rx_buf[0]; ret = ims_bme280_read_register(bme, IMS_BME280_REG_DIG_H2_L, rx_buf, 0x02); // H2 if (ret == IMS_FAIL) return ret; bme->trim.dig_H2 = (int16_t)IMS_BME280_CONCAT_BYTES(rx_buf[1], rx_buf[0]); ret = ims_bme280_read_register(bme, IMS_BME280_REG_DIG_H3, rx_buf, 0x01); // H3 if (ret == IMS_FAIL) return ret; bme->trim.dig_H3 = (uint8_t)rx_buf[0]; ret = ims_bme280_read_register(bme, IMS_BME280_REG_DIG_H4_H, rx_buf, 0x02); // H4 if (ret == IMS_FAIL) return ret; bme->trim.dig_H4 = (int16_t)(((int8_t)rx_buf[0] << 0x04) | (rx_buf[1] & 0x0F)); ret = ims_bme280_read_register(bme, IMS_BME280_REG_DIG_H5_L, rx_buf, 0x02); // H5 if (ret == IMS_FAIL) return ret; bme->trim.dig_H5 = (int16_t)(((int8_t)rx_buf[1] << 0x04) | (rx_buf[0] >> 0x04)); ret = ims_bme280_read_register(bme, IMS_BME280_REG_DIG_H6, rx_buf, 0x01); // H6 if (ret == IMS_FAIL) return ret; bme->trim.dig_H6 = (int8_t)rx_buf[0]; return IMS_SUCCESS; } static ims_ret_t ims_bme280_set_mode(ims_bme280_t *bme, ims_bme280_mode_t mode) { ims_ret_t ret; uint8_t ctrl_meas; ret = ims_bme280_read_register(bme, IMS_BME280_REG_CTRL_MEAS, &ctrl_meas, 1U); if (ret != IMS_SUCCESS) { return ret; } if (((ctrl_meas & IMS_BME280_REG_CTRL_MEAS_MODE_Msk) >> IMS_BME280_REG_CTRL_MEAS_MODE_Pos) == 0x00U) { ctrl_meas |= ((mode << IMS_BME280_REG_CTRL_MEAS_MODE_Pos) & IMS_BME280_REG_CTRL_MEAS_MODE_Msk); } ret = ims_bme280_write_register(bme, IMS_BME280_REG_CTRL_MEAS, ctrl_meas); return ret; } static ims_ret_t ims_bme280_get_mode(ims_bme280_t *bme, ims_bme280_mode_t *mode) { ims_ret_t ret; uint8_t ctrl_meas; ret = ims_bme280_read_register(bme, IMS_BME280_REG_CTRL_MEAS, &ctrl_meas, 1U); if (ret != IMS_SUCCESS) return ret; *mode = (ctrl_meas >> IMS_BME280_REG_CTRL_MEAS_MODE_Pos) & IMS_BME280_REG_CTRL_MEAS_MODE_Msk; return IMS_SUCCESS; } static ims_ret_t ims_bme280_wait_measure_complete(ims_bme280_t *bme, uint32_t timeout_ms) { ims_ret_t ret; uint8_t loop_count = 0U; uint8_t status; do { bme->cb.delay(bme->pdev, 5); ret = ims_bme280_read_register(bme, IMS_BME280_REG_STATUS, &status, 0x01); if (ret != IMS_SUCCESS) return IMS_FAIL; loop_count++; if (loop_count * 5 > timeout_ms) { return IMS_FAIL; } } while ((status & IMS_BME280_REG_STATUS_MEASURING_Msk) == 0U); return IMS_SUCCESS; } static ims_ret_t ims_bme280_read_raw_data(ims_bme280_t *bme, uint32_t *raw_t, uint32_t *raw_p, uint32_t *raw_h) { ims_ret_t ret; uint8_t measured_data[8]; ret = ims_bme280_read_register(bme, IMS_BME280_REG_PRESS_MSB, measured_data, 0x08); if (ret != IMS_SUCCESS) return IMS_FAIL; *raw_p = (measured_data[0] << 12) | (measured_data[1] << 0x04) | (measured_data[2] >> 0x04); *raw_t = (measured_data[3] << 12) | (measured_data[4] << 0x04) | (measured_data[5] >> 0x04); *raw_h = (measured_data[6] << 8) | (measured_data[7]); return IMS_SUCCESS; } static ims_ret_t ims_bme280_read_register(ims_bme280_t *bme, uint8_t reg, uint8_t *data, uint16_t len) { ims_i2c_xfer_desc_t xfer_desc = { .tx_size = 1U, .tx_data = ®, .rx_size = len, .rx_data = data, }; return bme->cb.i2c_xfer(bme->pdev, &xfer_desc); } static ims_ret_t ims_bme280_write_register(ims_bme280_t *bme, uint8_t reg, uint8_t data) { uint8_t tx_buf[2] = {reg, data}; ims_i2c_xfer_desc_t xfer_desc = { .tx_size = 2U, .tx_data = tx_buf, .rx_size = 0U, .rx_data = NULL, }; return bme->cb.i2c_xfer(bme->pdev, &xfer_desc); } #ifdef IMS_CFG_DHT_BME280_ENABLE_FLOAT static double ims_bme280_compensate_T_double(ims_bme280_t *bme, int32_t adc_T) { double var1, var2, T; var1 = (((double)adc_T) / 16384.0 - ((double)bme->trim.dig_T1) / 1024.0) * ((double)bme->trim.dig_T2); var2 = ((((double)adc_T) / 131072.0 - ((double)bme->trim.dig_T1) / 8192.0) * (((double)adc_T) / 131072.0 - ((double)bme->trim.dig_T1) / 8192.0)) * ((double)bme->trim.dig_T3); bme->t_fine = (int32_t)(var1 + var2); T = (var1 + var2) / 5120.0; return T; } static double ims_bme280_compensate_P_double(ims_bme280_t *bme, int32_t adc_P) { double var1, var2, p; var1 = ((double)bme->t_fine / 2.0) - 64000.0; var2 = var1 * var1 * ((double)bme->trim.dig_P6) / 32768.0; var2 = var2 + var1 * ((double)bme->trim.dig_P5) * 2.0; var2 = (var2 / 4.0) + (((double)bme->trim.dig_P4) * 65536.0); var1 = (((double)bme->trim.dig_P3) * var1 * var1 / 524288.0 + ((double)bme->trim.dig_P2) * var1) / 524288.0; var1 = (1.0 + var1 / 32768.0) * ((double)bme->trim.dig_P1); if (var1 == 0.0) { return 0; // avoid exception caused by division by zero } p = 1048576.0 - (double)adc_P; p = (p - (var2 / 4096.0)) * 6250.0 / var1; var1 = ((double)bme->trim.dig_P9) * p * p / 2147483648.0; var2 = p * ((double)bme->trim.dig_P8) / 32768.0; p = p + (var1 + var2 + ((double)bme->trim.dig_P7)) / 16.0; return p; } static double ims_bme280_compensate_H_double(ims_bme280_t *bme, int32_t adc_H) { double var_H; var_H = (((double)bme->t_fine) - 76800.0); var_H = (adc_H - (((double)bme->trim.dig_H4) * 64.0 + ((double)bme->trim.dig_H5) / 16384.0 * var_H)) * (((double)bme->trim.dig_H2) / 65536.0 * (1.0 + ((double)bme->trim.dig_H6) / 67108864.0 * var_H * (1.0 + ((double)bme->trim.dig_H3) / 67108864.0 * var_H))); var_H = var_H * (1.0 - ((double)bme->trim.dig_H1) * var_H / 524288.0); if (var_H > 100.0) var_H = 100.0; else if (var_H < 0.0) var_H = 0.0; return var_H; } #else static int32_t ims_bme280_compensate_T_int32(ims_bme280_t *bme, int32_t adc_T) { int32_t var1, var2, T; var1 = ((((adc_T >> 3) - ((int32_t)bme->trim.dig_T1 << 1))) * ((int32_t)bme->trim.dig_T2)) >> 11; var2 = (((((adc_T >> 4) - ((int32_t)bme->trim.dig_T1)) * ((adc_T >> 4) - ((int32_t)bme->trim.dig_T1))) >> 12) * ((int32_t)bme->trim.dig_T3)) >> 14; bme->t_fine = var1 + var2; T = (bme->t_fine * 5 + 128) >> 8; return T; } static uint32_t ims_bme280_compensate_P_int64(ims_bme280_t *bme, int32_t adc_P) { int64_t var1, var2, p; var1 = ((int64_t)bme->t_fine) - 128000; var2 = var1 * var1 * (int64_t)bme->trim.dig_P6; var2 = var2 + ((var1 * (int64_t)bme->trim.dig_P5) << 17); var2 = var2 + (((int64_t)bme->trim.dig_P4) << 35); var1 = ((var1 * var1 * (int64_t)bme->trim.dig_P3) >> 8) + ((var1 * (int64_t)bme->trim.dig_P2) << 12); var1 = (((((int64_t)1) << 47) + var1)) * ((int64_t)bme->trim.dig_P1) >> 33; if (var1 == 0) { return 0; // avoid exception caused by division by zero } p = 1048576 - adc_P; p = (((p << 31) - var2) * 3125) / var1; var1 = (((int64_t)bme->trim.dig_P9) * (p >> 13) * (p >> 13)) >> 25; var2 = (((int64_t)bme->trim.dig_P8) * p) >> 19; p = ((p + var1 + var2) >> 8) + (((int64_t)bme->trim.dig_P7) << 4); return (uint32_t)p; } static uint32_t ims_bme280_compensate_H_int32(ims_bme280_t *bme, int32_t adc_H) { int32_t v_x1_u32r; v_x1_u32r = (bme->t_fine - ((int32_t)76800)); v_x1_u32r = (((((adc_H << 14) - (((int32_t)bme->trim.dig_H4) << 20) - (((int32_t)bme->trim.dig_H5) * v_x1_u32r)) + ((int32_t)16384)) >> 15) * (((((((v_x1_u32r * ((int32_t)bme->trim.dig_H6)) >> 10) * (((v_x1_u32r * ((int32_t)bme->trim.dig_H3)) >> 11) + ((int32_t)32768))) >> 10) + ((int32_t)2097152)) * ((int32_t)bme->trim.dig_H2) + 8192) >> 14)); v_x1_u32r = (v_x1_u32r - (((((v_x1_u32r >> 15) * (v_x1_u32r >> 15)) >> 7) * ((int32_t)bme->trim.dig_H1)) >> 4)); v_x1_u32r = (v_x1_u32r < 0 ? 0 : v_x1_u32r); v_x1_u32r = (v_x1_u32r > 419430400 ? 419430400 : v_x1_u32r); return (uint32_t)(v_x1_u32r >> 12); } #endif