Skip to content

Commit 3ef81fe

Browse files
laurenmurphyx64nashif
authored andcommitted
drivers: sensor: bme280: use int math in decode q31 conv
Fix decoder to use integer math when converting readings to Q31. Fixes #77295 Signed-off-by: Lauren Murphy <[email protected]>
1 parent bb3efaa commit 3ef81fe

File tree

2 files changed

+25
-50
lines changed

2 files changed

+25
-50
lines changed

drivers/sensor/bosch/bme280/bme280.h

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -160,6 +160,17 @@ extern const struct bme280_bus_io bme280_bus_io_i2c;
160160
BME280_TEMP_OVER | \
161161
BME280_MODE_SLEEP)
162162

163+
/* Convert to Q15.16 */
164+
#define BME280_TEMP_CONV 100
165+
#define BME280_TEMP_SHIFT 16
166+
/* Treat UQ24.8 as Q23.8
167+
* Need to divide by 1000 to convert to kPa
168+
*/
169+
#define BME280_PRESS_CONV_KPA 1000
170+
#define BME280_PRESS_SHIFT 23
171+
/* Treat UQ22.10 as Q21.10 */
172+
#define BME280_HUM_SHIFT 21
173+
163174
struct bme280_reading {
164175
/* Compensated values. */
165176
int32_t comp_temp;

drivers/sensor/bosch/bme280/bme280_decoder.c

Lines changed: 14 additions & 50 deletions
Original file line numberDiff line numberDiff line change
@@ -54,50 +54,8 @@ static int bme280_decoder_get_size_info(struct sensor_chan_spec chan_spec, size_
5454
}
5555
}
5656

57-
#define BME280_HUM_SHIFT (22)
58-
#define BME280_PRESS_SHIFT (24)
59-
#define BME280_TEMP_SHIFT (24)
60-
61-
static void bme280_convert_double_to_q31(double reading, int32_t shift, q31_t *out)
62-
{
63-
reading = reading * pow(2, 31 - shift);
64-
65-
int64_t reading_round = (reading < 0) ? (reading - 0.5) : (reading + 0.5);
66-
int32_t reading_q31 = CLAMP(reading_round, INT32_MIN, INT32_MAX);
67-
68-
if (reading_q31 < 0) {
69-
reading_q31 = abs(reading_q31);
70-
reading_q31 = ~reading_q31;
71-
reading_q31++;
72-
}
73-
74-
*out = reading_q31;
75-
}
76-
77-
/* Refer to bme280.c bme280_channel_get() */
78-
static void bme280_convert_signed_temp_raw_to_q31(int32_t reading, q31_t *out)
79-
{
80-
double temp_double = reading / 100.0;
81-
82-
bme280_convert_double_to_q31(temp_double, BME280_TEMP_SHIFT, out);
83-
}
84-
85-
static void bme280_convert_unsigned_pressure_raw_to_q31(uint32_t reading, q31_t *out)
86-
{
87-
double press_double = (reading / 256.0) / 1000.0; /* Pa -> hPa */
88-
89-
bme280_convert_double_to_q31(press_double, BME280_PRESS_SHIFT, out);
90-
}
91-
92-
static void bme280_convert_unsigned_humidity_raw_to_q31(uint32_t reading, q31_t *out)
93-
{
94-
double hum_double = (reading / 1024.0);
95-
96-
bme280_convert_double_to_q31(hum_double, BME280_HUM_SHIFT, out);
97-
}
98-
9957
static int bme280_decoder_decode(const uint8_t *buffer, struct sensor_chan_spec chan_spec,
100-
uint32_t *fit, uint16_t max_count, void *data_out)
58+
uint32_t *fit, uint16_t max_count, void *data_out)
10159
{
10260
const struct bme280_encoded_data *edata = (const struct bme280_encoded_data *)buffer;
10361

@@ -113,26 +71,33 @@ static int bme280_decoder_decode(const uint8_t *buffer, struct sensor_chan_spec
11371
switch (chan_spec.chan_type) {
11472
case SENSOR_CHAN_AMBIENT_TEMP:
11573
if (edata->has_temp) {
116-
bme280_convert_signed_temp_raw_to_q31(edata->reading.comp_temp,
117-
&out->readings[0].temperature);
74+
int32_t readq = edata->reading.comp_temp * pow(2, 31 - BME280_TEMP_SHIFT);
75+
int32_t convq = BME280_TEMP_CONV * pow(2, 31 - BME280_TEMP_SHIFT);
76+
77+
out->readings[0].temperature =
78+
(int32_t)((((int64_t)readq) << (31 - BME280_TEMP_SHIFT)) /
79+
((int64_t)convq));
11880
out->shift = BME280_TEMP_SHIFT;
11981
} else {
12082
return -ENODATA;
12183
}
12284
break;
12385
case SENSOR_CHAN_PRESS:
12486
if (edata->has_press) {
125-
bme280_convert_unsigned_pressure_raw_to_q31(edata->reading.comp_press,
126-
&out->readings[0].pressure);
87+
int32_t readq = edata->reading.comp_press;
88+
int32_t convq = BME280_PRESS_CONV_KPA * pow(2, 31 - BME280_PRESS_SHIFT);
89+
90+
out->readings[0].pressure =
91+
(int32_t)((((int64_t)readq) << (31 - BME280_PRESS_SHIFT)) /
92+
((int64_t)convq));
12793
out->shift = BME280_PRESS_SHIFT;
12894
} else {
12995
return -ENODATA;
13096
}
13197
break;
13298
case SENSOR_CHAN_HUMIDITY:
13399
if (edata->has_humidity) {
134-
bme280_convert_unsigned_humidity_raw_to_q31(edata->reading.comp_humidity,
135-
&out->readings[0].humidity);
100+
out->readings[0].humidity = edata->reading.comp_humidity;
136101
out->shift = BME280_HUM_SHIFT;
137102
} else {
138103
return -ENODATA;
@@ -147,7 +112,6 @@ static int bme280_decoder_decode(const uint8_t *buffer, struct sensor_chan_spec
147112
return 1;
148113
}
149114

150-
151115
SENSOR_DECODER_API_DT_DEFINE() = {
152116
.get_frame_count = bme280_decoder_get_frame_count,
153117
.get_size_info = bme280_decoder_get_size_info,

0 commit comments

Comments
 (0)