drivers: sensor: bmi08x: fix interfaceand trigger

1. Temperature Interface
According to BMI08x datasheet, temperature reading
requires both MSB and LSB bytes to be read and
processed correctly.

Temp data processing should follow the formula:
Temp in °C = (temp_msb * 8) + (temp_lsb / 32)

This patch implements the correct reading
sequence and calculation method as specified
in the datasheet.

2. Trigger Setting
Previously we set handler and then trigger struct.
However under some situation, as long as we set
the handler, we get into ISR immediately and never
set trigger struct.
I simply changed the sequence.

Testing:
- Verified temperature readings match datasheet
- Tested on stm32f407igh board with BMI08x sensor

Fixes: #82375

Signed-off-by: Wenxi Xu <xuwenxi0517@gmail.com>
This commit is contained in:
Wenxi Xu 2024-12-10 06:29:30 +00:00 committed by Benjamin Cabé
parent d36334a08c
commit a490c90dc3
3 changed files with 30 additions and 5 deletions

View file

@ -454,16 +454,41 @@ static int bmi08x_temp_channel_get(const struct device *dev, struct sensor_value
{ {
uint16_t temp_raw = 0U; uint16_t temp_raw = 0U;
int32_t temp_micro = 0; int32_t temp_micro = 0;
int16_t temp_int11 = 0;
int ret; int ret;
ret = bmi08x_accel_word_read(dev, BMI08X_REG_TEMP_MSB, &temp_raw); ret = bmi08x_accel_word_read(dev, BMI08X_REG_TEMP_MSB, &temp_raw);
if (ret < 0) { if (!ret) {
temp_int11 = (temp_raw & 0xFF) << 3;
} else {
LOG_ERR("Error reading BMI08X_REG_TEMP_MSB. (err %d)", ret);
return ret; return ret;
} }
/* the scale is 1/2^5/LSB = 31250 micro degrees */ if (temp_raw == 0x80) {
temp_micro = BMI08X_TEMP_OFFSET * 1000000ULL + temp_raw * 31250ULL; /* temperature invalid */
LOG_ERR("BMI08X returned invalid temperature.");
return -ENODATA;
}
ret = bmi08x_accel_word_read(dev, BMI08X_REG_TEMP_LSB, &temp_raw);
if (!ret) {
temp_int11 |= (temp_raw & 0xE0) >> 5;
} else {
LOG_ERR("Error reading BMI08X_REG_TEMP_LSB. (err %d)", ret);
return ret;
}
/*
* int11 type ranges in [-1024, 1023]
* the 11st bit declares +/-
* if larger than 1023, it is negative.
*/
if (temp_int11 > 1023) {
temp_int11 -= 2048;
}
/* the value ranges in [-504, 496] */
/* the scale is 0.125°C/LSB = 125 micro degrees */
temp_micro = temp_int11 * 125 + 23 * 1000000;
val->val1 = temp_micro / 1000000ULL; val->val1 = temp_micro / 1000000ULL;
val->val2 = temp_micro % 1000000ULL; val->val2 = temp_micro % 1000000ULL;

View file

@ -89,8 +89,8 @@ int bmi08x_trigger_set_acc(const struct device *dev, const struct sensor_trigger
struct bmi08x_accel_data *data = dev->data; struct bmi08x_accel_data *data = dev->data;
if ((trig->chan == SENSOR_CHAN_ACCEL_XYZ) && (trig->type == SENSOR_TRIG_DATA_READY)) { if ((trig->chan == SENSOR_CHAN_ACCEL_XYZ) && (trig->type == SENSOR_TRIG_DATA_READY)) {
data->handler_drdy_acc = handler;
data->drdy_trig_acc = trig; data->drdy_trig_acc = trig;
data->handler_drdy_acc = handler;
return 0; return 0;
} }

View file

@ -89,8 +89,8 @@ int bmi08x_trigger_set_gyr(const struct device *dev, const struct sensor_trigger
struct bmi08x_gyro_data *data = dev->data; struct bmi08x_gyro_data *data = dev->data;
if ((trig->chan == SENSOR_CHAN_GYRO_XYZ) && (trig->type == SENSOR_TRIG_DATA_READY)) { if ((trig->chan == SENSOR_CHAN_GYRO_XYZ) && (trig->type == SENSOR_TRIG_DATA_READY)) {
data->handler_drdy_gyr = handler;
data->drdy_trig_gyr = trig; data->drdy_trig_gyr = trig;
data->handler_drdy_gyr = handler;
return 0; return 0;
} }