Fixed overflow in pressure compensation

This commit is contained in:
Daniele Lacamera 2022-09-01 10:16:42 +02:00
parent d2f473c4a7
commit 86c36c4c57

View file

@ -66,11 +66,11 @@ static void init_i2c0(void)
#define BMP180_OSS_UHR 3
#define BMP180_REG_T 0x2E
static const uint32_t BMP180_OSS = BMP180_OSS_STD;
static const uint32_t BMP180_OSS = BMP180_OSS_UHR;
static const uint8_t BMP180_REG_P_ARRAY[4] = {0x34, 0x74, 0xB4, 0xF4};
static const uint8_t BMP180_REG_P_TIME[4] = {5, 8, 14, 26};
#define BMP180_REG_P BMP180_REG_P_ARRAY[BMP180_OSS]
#define BMP180_P_CONVERSION_TIME BMP180_REG_P_TIME[BMP180_OSS_STD]
#define BMP180_P_CONVERSION_TIME BMP180_REG_P_TIME[BMP180_OSS]
struct __attribute__((packed)) bmp180_cal_regs {
union {
@ -101,26 +101,26 @@ static int32_t compensate_temperature(int16_t ut)
/* Pressure [in Pa, 1 Pa = 0.01mbar] */
static uint32_t compensate_pressure(uint32_t up)
{
uint32_t x1, x2, x3;
uint64_t x1, x2, x3;
uint32_t p;
BMP180.B6 = BMP180.B5 - 4000;
x1 = (BMP180.creg.B2 * ((BMP180.B6 * BMP180.B6) >> 12)) >> 11;
x2 = (BMP180.creg.AC2 * BMP180.B6) >> 11;
x3 = x1 + x2;
BMP180.B3 = ((((int32_t)BMP180.creg.AC1 * 4 + x3) << BMP180_OSS) + 2) >> 2;
BMP180.B3 = ((((int64_t)BMP180.creg.AC1 * 4 + x3) << BMP180_OSS) + 2) >> 2;
x1 = (BMP180.creg.AC3 * BMP180.B6) >> 13;
x2 = (BMP180.creg.B1 * ((BMP180.B6 * BMP180.B6) >> 12)) >> 16;
x3 = ((x1 + x2) + 2) >> 2;
BMP180.B4 = (BMP180.creg.AC4 * (x3 + 32768)) >> 15;
BMP180.B7 = (up - BMP180.B3) * (50000 >> BMP180_OSS);
if (BMP180.B7 < 0x80000000)
BMP180.B4 = (BMP180.creg.AC4 * (x3 + 32768UL)) >> 15;
BMP180.B7 = (up - BMP180.B3) * (50000UL >> BMP180_OSS);
if (BMP180.B7 < 0x80000000UL)
p = (BMP180.B7 * 2) / BMP180.B4;
else
p = (BMP180.B7 / BMP180.B4) * 2;
x1 = (p >> 8) * (p >> 8);
x1 = (x1 * 3038) >> 16;
x2 = (-7357 * p) >> 16;
p += (x1 + x2 + 3791) >> 4;
x1 = (x1 * 3038UL) >> 16;
x2 = (-7357UL * p) >> 16;
p += (x1 + x2 + 3791UL) >> 4;
return p;
}
@ -257,7 +257,7 @@ static uint32_t bmp180_read_P(void)
while (I2C_CTL0(I2C0) & 0x0200)
;
delay_1ms(5);
delay_1ms(BMP180_P_CONVERSION_TIME);
i2c_wait_busy();
i2c_start_on_bus(I2C0);
while (!i2c_flag_get(I2C0, I2C_FLAG_SBSEND))
@ -294,7 +294,7 @@ static uint32_t bmp180_read_P(void)
i2c_stop_on_bus(I2C0);
while (I2C_CTL0(I2C0) & 0x0200)
;
return (uint32_t)((data_xlsb + (data_lsb << 8) + (data_msb << 16)) >> 3);
return (uint32_t)((data_xlsb + (data_lsb << 8) + (data_msb << 16)) >> (8 - BMP180_OSS));
}
int main(void)
@ -346,8 +346,8 @@ int main(void)
pressure = compensate_pressure(up);
snprintf(tmp, MAX_ROW - 1, "T: %d", temperature);
snprintf(prs, MAX_ROW - 1, "p: %u", pressure);
//snprintf(tmp, MAX_ROW - 1, "T: %d", ut);
//snprintf(prs, MAX_ROW - 1, "p: %u", up);
snprintf(dte, MAX_ROW - 1, "AC1: %x", BMP180.creg.AC1);
snprintf(gps, MAX_ROW - 1, "MD: %x", BMP180.creg.MD);
/* Display background */
LCD_Clear(BLACK);
BACK_COLOR=BLACK;