drivers: sensor: tmp108: Handle negative values correctly
Negative temperatures were converted to the sensor_value struct incorrectly. This fixes the causes: signed/unsigned mixups and integer overflows. Also clarified temperature calculation using multiplier/divisor config values. Fixes #68240 Signed-off-by: Boris Mulder <b.mulder@innoseis.com>
This commit is contained in:
parent
d83c63ecce
commit
f87143d919
|
@ -152,9 +152,9 @@ static int tmp108_channel_get(const struct device *dev,
|
||||||
return -ENOTSUP;
|
return -ENOTSUP;
|
||||||
}
|
}
|
||||||
|
|
||||||
uval = ((int32_t)(drv_data->sample) * TMP108_TEMP_MULTIPLIER(dev)) >> 4U;
|
uval = ((int32_t)drv_data->sample * TMP108_TEMP_MULTIPLIER(dev)) / TMP108_TEMP_DIVISOR(dev);
|
||||||
val->val1 = uval / 1000000U;
|
val->val1 = uval / 1000000;
|
||||||
val->val2 = uval % 1000000U;
|
val->val2 = uval % 1000000;
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
@ -237,7 +237,7 @@ static int tmp108_attr_set(const struct device *dev,
|
||||||
|
|
||||||
case SENSOR_ATTR_LOWER_THRESH:
|
case SENSOR_ATTR_LOWER_THRESH:
|
||||||
uval = val->val1 * 1000000 + val->val2;
|
uval = val->val1 * 1000000 + val->val2;
|
||||||
reg_value = (uval << 4U) / TMP108_TEMP_MULTIPLIER(dev);
|
reg_value = (uval * TMP108_TEMP_DIVISOR(dev)) / TMP108_TEMP_MULTIPLIER(dev);
|
||||||
result = tmp108_reg_write(dev,
|
result = tmp108_reg_write(dev,
|
||||||
TI_TMP108_REG_LOW_LIMIT,
|
TI_TMP108_REG_LOW_LIMIT,
|
||||||
reg_value);
|
reg_value);
|
||||||
|
@ -245,7 +245,7 @@ static int tmp108_attr_set(const struct device *dev,
|
||||||
|
|
||||||
case SENSOR_ATTR_UPPER_THRESH:
|
case SENSOR_ATTR_UPPER_THRESH:
|
||||||
uval = val->val1 * 1000000 + val->val2;
|
uval = val->val1 * 1000000 + val->val2;
|
||||||
reg_value = (uval << 4U) / TMP108_TEMP_MULTIPLIER(dev);
|
reg_value = (uval * TMP108_TEMP_DIVISOR(dev)) / TMP108_TEMP_MULTIPLIER(dev);
|
||||||
result = tmp108_reg_write(dev,
|
result = tmp108_reg_write(dev,
|
||||||
TI_TMP108_REG_HIGH_LIMIT,
|
TI_TMP108_REG_HIGH_LIMIT,
|
||||||
reg_value);
|
reg_value);
|
||||||
|
|
|
@ -29,7 +29,8 @@
|
||||||
.CONF_POL = 0x0400, \
|
.CONF_POL = 0x0400, \
|
||||||
.CONF_M0 = 0x8000, \
|
.CONF_M0 = 0x8000, \
|
||||||
.CONF_RST = 0x0080, \
|
.CONF_RST = 0x0080, \
|
||||||
.TEMP_MULT = 125000, \
|
.TEMP_MULT = 15625, \
|
||||||
|
.TEMP_DIV = 2, \
|
||||||
.WAKEUP_TIME_IN_MS = 120 }
|
.WAKEUP_TIME_IN_MS = 120 }
|
||||||
|
|
||||||
#define TI_TMP108_CONF {.CONF_HYS0 = 0x0010, \
|
#define TI_TMP108_CONF {.CONF_HYS0 = 0x0010, \
|
||||||
|
@ -41,7 +42,8 @@
|
||||||
.CONF_CR0 = 0x2000, \
|
.CONF_CR0 = 0x2000, \
|
||||||
.CONF_CR1 = 0x4000, \
|
.CONF_CR1 = 0x4000, \
|
||||||
.CONF_RST = 0x0022, \
|
.CONF_RST = 0x0022, \
|
||||||
.TEMP_MULT = 62500, \
|
.TEMP_MULT = 15625, \
|
||||||
|
.TEMP_DIV = 4, \
|
||||||
.WAKEUP_TIME_IN_MS = 30 }
|
.WAKEUP_TIME_IN_MS = 30 }
|
||||||
|
|
||||||
#define TI_TMP108_MODE_SHUTDOWN(x) 0
|
#define TI_TMP108_MODE_SHUTDOWN(x) 0
|
||||||
|
@ -77,6 +79,7 @@
|
||||||
#define TI_TMP108_CONF_M0(x) TI_TMP108_GET_CONF(x, CONF_M0)
|
#define TI_TMP108_CONF_M0(x) TI_TMP108_GET_CONF(x, CONF_M0)
|
||||||
|
|
||||||
#define TMP108_TEMP_MULTIPLIER(x) TI_TMP108_GET_CONF(x, TEMP_MULT)
|
#define TMP108_TEMP_MULTIPLIER(x) TI_TMP108_GET_CONF(x, TEMP_MULT)
|
||||||
|
#define TMP108_TEMP_DIVISOR(x) TI_TMP108_GET_CONF(x, TEMP_DIV)
|
||||||
#define TMP108_WAKEUP_TIME_IN_MS(x) TI_TMP108_GET_CONF(x, WAKEUP_TIME_IN_MS)
|
#define TMP108_WAKEUP_TIME_IN_MS(x) TI_TMP108_GET_CONF(x, WAKEUP_TIME_IN_MS)
|
||||||
#define TMP108_CONF_RST(x) TI_TMP108_GET_CONF(x, CONF_RST)
|
#define TMP108_CONF_RST(x) TI_TMP108_GET_CONF(x, CONF_RST)
|
||||||
|
|
||||||
|
@ -91,7 +94,8 @@ struct tmp_108_reg_def {
|
||||||
uint16_t CONF_TM; /** Thermostat mode setting bit */
|
uint16_t CONF_TM; /** Thermostat mode setting bit */
|
||||||
uint16_t CONF_HYS1; /** Temperature hysteresis config 1 bit */
|
uint16_t CONF_HYS1; /** Temperature hysteresis config 1 bit */
|
||||||
uint16_t CONF_HYS0; /** Temperature hysteresis config 2 bit */
|
uint16_t CONF_HYS0; /** Temperature hysteresis config 2 bit */
|
||||||
uint32_t TEMP_MULT; /** Temperature multiplier */
|
int32_t TEMP_MULT; /** Temperature multiplier */
|
||||||
|
int32_t TEMP_DIV; /** Temperature divisor */
|
||||||
uint16_t WAKEUP_TIME_IN_MS; /** Wake up and conversion time from one shot */
|
uint16_t WAKEUP_TIME_IN_MS; /** Wake up and conversion time from one shot */
|
||||||
uint16_t CONF_RST; /** default reset values on init */
|
uint16_t CONF_RST; /** default reset values on init */
|
||||||
};
|
};
|
||||||
|
@ -107,7 +111,7 @@ struct tmp108_config {
|
||||||
struct tmp108_data {
|
struct tmp108_data {
|
||||||
const struct device *tmp108_dev;
|
const struct device *tmp108_dev;
|
||||||
|
|
||||||
uint16_t sample;
|
int16_t sample;
|
||||||
|
|
||||||
bool one_shot_mode;
|
bool one_shot_mode;
|
||||||
|
|
||||||
|
|
Loading…
Reference in a new issue