drivers: sensor: ina237: add shunt voltage support
Add ability to retrieve the shunt voltage if the end user wants to do the power calculation manually to handle negative power values. Signed-off-by: Eric Holmberg <eric.holmberg@northriversystems.co.nz>
This commit is contained in:
parent
a70d056513
commit
19e44ae9a0
|
@ -26,6 +26,20 @@ config INA237
|
|||
help
|
||||
Enable driver for INA237.
|
||||
|
||||
config INA237_VSHUNT
|
||||
bool "INA237 VShunt Measurement Enable"
|
||||
depends on DT_HAS_TI_INA237_ENABLED
|
||||
help
|
||||
Enable shunt voltage measurement for INA237.
|
||||
|
||||
This is the actual shunt voltage measured which is scaled within the
|
||||
INA237 based upon the SHUNT_CAL register. This value is useful for
|
||||
looking at measurement noise or debugging the SHUNT_CAL value.
|
||||
|
||||
Note that enabling this option requires an extra I2C read when
|
||||
SENSOR_CHAN_ALL is selected, so only enable if the shunt voltage
|
||||
measurement is required.
|
||||
|
||||
config INA230_TRIGGER
|
||||
bool "INA230 trigger mode"
|
||||
depends on INA230
|
||||
|
|
|
@ -65,6 +65,18 @@ static int ina237_channel_get(const struct device *dev, enum sensor_channel chan
|
|||
INA237_POWER_TO_uW((uint64_t)data->power * config->current_lsb));
|
||||
break;
|
||||
|
||||
#ifdef CONFIG_INA237_VSHUNT
|
||||
case SENSOR_CHAN_VSHUNT:
|
||||
if (config->config & INA237_CFG_HIGH_PRECISION) {
|
||||
/* high-resolution mode - 1.25 uV/bit, sensor value is in mV */
|
||||
micro_s32_to_sensor_value(val, data->shunt_voltage * 1250);
|
||||
} else {
|
||||
/* standard-resolution - 5 uV/bit -> nano-volts */
|
||||
micro_s32_to_sensor_value(val, data->shunt_voltage * 5000);
|
||||
}
|
||||
break;
|
||||
#endif /* CONFIG_INA237_VSHUNT */
|
||||
|
||||
case SENSOR_CHAN_DIE_TEMP:
|
||||
micro_s32_to_sensor_value(val, INA237_DIETEMP_TO_uDegC(data->die_temp));
|
||||
break;
|
||||
|
@ -165,6 +177,16 @@ static int ina237_read_data(const struct device *dev)
|
|||
}
|
||||
}
|
||||
|
||||
#ifdef CONFIG_INA237_VSHUNT
|
||||
if ((data->chan == SENSOR_CHAN_ALL) || (data->chan == SENSOR_CHAN_VSHUNT)) {
|
||||
ret = ina23x_reg_read_16(&config->bus, INA237_REG_SHUNT_VOLT, &data->shunt_voltage);
|
||||
if (ret < 0) {
|
||||
LOG_ERR("Failed to read shunt voltage");
|
||||
return ret;
|
||||
}
|
||||
}
|
||||
#endif /* CONFIG_INA237_VSHUNT */
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
@ -179,7 +201,11 @@ static int ina237_sample_fetch(const struct device *dev, enum sensor_channel cha
|
|||
struct ina237_data *data = dev->data;
|
||||
|
||||
if (chan != SENSOR_CHAN_ALL && chan != SENSOR_CHAN_VOLTAGE && chan != SENSOR_CHAN_CURRENT &&
|
||||
chan != SENSOR_CHAN_POWER && chan != SENSOR_CHAN_DIE_TEMP) {
|
||||
chan != SENSOR_CHAN_POWER &&
|
||||
#ifdef CONFIG_INA237_VSHUNT
|
||||
chan != SENSOR_CHAN_VSHUNT &&
|
||||
#endif /* CONFIG_INA237_VSHUNT */
|
||||
chan != SENSOR_CHAN_DIE_TEMP) {
|
||||
return -ENOTSUP;
|
||||
}
|
||||
|
||||
|
|
|
@ -43,6 +43,9 @@ struct ina237_data {
|
|||
uint16_t bus_voltage;
|
||||
uint32_t power;
|
||||
int16_t die_temp;
|
||||
#ifdef CONFIG_INA237_VSHUNT
|
||||
int16_t shunt_voltage;
|
||||
#endif
|
||||
enum sensor_channel chan;
|
||||
struct ina23x_trigger trigger;
|
||||
};
|
||||
|
|
|
@ -124,6 +124,10 @@ enum sensor_channel {
|
|||
|
||||
/** Voltage, in volts **/
|
||||
SENSOR_CHAN_VOLTAGE,
|
||||
|
||||
/** Current Shunt Voltage in milli-volts **/
|
||||
SENSOR_CHAN_VSHUNT,
|
||||
|
||||
/** Current, in amps **/
|
||||
SENSOR_CHAN_CURRENT,
|
||||
/** Power in watts **/
|
||||
|
|
|
@ -10,5 +10,6 @@ CONFIG_I2C_EMUL=y
|
|||
CONFIG_I2C_LOG_LEVEL_DBG=y
|
||||
|
||||
CONFIG_INA237=y
|
||||
CONFIG_INA237_VSHUNT=y
|
||||
|
||||
CONFIG_CBPRINTF_FP_SUPPORT=y
|
||||
|
|
|
@ -197,6 +197,51 @@ static void test_temperature(struct ina237_fixture *fixture)
|
|||
}
|
||||
}
|
||||
|
||||
static void test_vshunt(struct ina237_fixture *fixture)
|
||||
{
|
||||
zassert_not_null(fixture->mock);
|
||||
|
||||
/* 16-bit signed value for voltage register (but always positive) 3.125 mV/bit */
|
||||
const int16_t vshunt_reg_vectors[] = {
|
||||
32767, /* maximum shunt voltage of 163.84 mV or 40.96 mV */
|
||||
27200,
|
||||
1000,
|
||||
100,
|
||||
1,
|
||||
0,
|
||||
-1,
|
||||
-100,
|
||||
-1000,
|
||||
-32768, /* minimum shunt voltage of -163.84 mV or -40.96 mV */
|
||||
};
|
||||
|
||||
for (int idx = 0; idx < ARRAY_SIZE(vshunt_reg_vectors); idx++) {
|
||||
struct sensor_value sensor_val;
|
||||
|
||||
ina237_mock_set_register(fixture->mock->data, INA237_REG_SHUNT_VOLT,
|
||||
vshunt_reg_vectors[idx]);
|
||||
|
||||
/* Verify sensor value is correct */
|
||||
zassert_ok(sensor_sample_fetch_chan(fixture->dev, SENSOR_CHAN_VSHUNT));
|
||||
zassert_ok(sensor_channel_get(fixture->dev, SENSOR_CHAN_VSHUNT, &sensor_val));
|
||||
|
||||
double vshunt_actual_mV = sensor_value_to_double(&sensor_val);
|
||||
double vshunt_expected_mV = vshunt_reg_vectors[idx];
|
||||
|
||||
if (fixture->config & INA237_CFG_HIGH_PRECISION) {
|
||||
/* High precision mode - 1.25 uV/bit = 1250 nV/bit*/
|
||||
vshunt_expected_mV *= 1000 * 1.250e-6;
|
||||
} else {
|
||||
/* Standard precision mode - 5 uV/bit = 5000 nV/bit */
|
||||
vshunt_expected_mV *= 1000 * 5e-6;
|
||||
}
|
||||
|
||||
zexpect_within(vshunt_expected_mV, vshunt_actual_mV, 1e-9,
|
||||
"For %d, Expected %.6f mV, got %.6f mV", vshunt_reg_vectors[idx],
|
||||
vshunt_expected_mV, vshunt_actual_mV);
|
||||
}
|
||||
}
|
||||
|
||||
/* Create a test fixture for each enabled ina237 device node */
|
||||
#define DT_DRV_COMPAT ti_ina237
|
||||
#define INA237_FIXTURE_ENTRY(inst) \
|
||||
|
@ -219,6 +264,7 @@ static struct ina237_fixture fixtures[] = {
|
|||
ZTEST(ina237_##inst, test_bus_voltage) { test_bus_voltage(&fixtures[inst]); } \
|
||||
ZTEST(ina237_##inst, test_power) { test_power(&fixtures[inst]); } \
|
||||
ZTEST(ina237_##inst, test_temperature) { test_temperature(&fixtures[inst]); } \
|
||||
ZTEST(ina237_##inst, test_vshunt) { test_vshunt(&fixtures[inst]); } \
|
||||
ZTEST_SUITE(ina237_##inst, NULL, NULL, NULL, NULL, NULL);
|
||||
|
||||
DT_INST_FOREACH_STATUS_OKAY(INA237_TESTS)
|
||||
|
|
Loading…
Reference in a new issue