test: sensor: ina230: Add INA236

Update tests to validate INA236 chip

Signed-off-by: Tomáš Juřena <jurenatomas@gmail.com>
This commit is contained in:
Tomáš Juřena 2024-08-23 16:11:09 +02:00 committed by Anas Nashif
commit 953436b185
4 changed files with 123 additions and 52 deletions

View file

@ -15,4 +15,12 @@
current-lsb-microamps = <1000>;
status = "okay";
};
ina236_default_test: ina236@41 {
compatible = "ti,ina236";
reg = <0x41>;
rshunt-micro-ohms = <2000>;
current-lsb-microamps = <1000>;
status = "okay";
};
};

View file

@ -5,7 +5,6 @@
*
* Emulator for the TI INA230 I2C power monitor
*/
#define DT_DRV_COMPAT ti_ina230
#include <zephyr/device.h>
#include <zephyr/drivers/emul.h>
@ -30,17 +29,23 @@ struct ina230_emul_cfg {
uint16_t addr;
};
#define MAX_REGS 0xff
struct ina230_emul_data {
struct ina230_reg ina230_regs[INA230_REGISTER_COUNT];
struct ina230_reg *regs;
};
static struct ina230_reg *get_register(struct ina230_emul_data *data, int reg)
{
for (int i = 0; i < INA230_REGISTER_COUNT; i++) {
if (data->ina230_regs[i].id == reg) {
return &data->ina230_regs[i];
struct ina230_reg *c_reg = data->regs;
while (c_reg->bytes) {
if (c_reg->id == reg) {
return c_reg;
}
c_reg++;
}
return NULL;
}
@ -151,12 +156,9 @@ static const struct i2c_emul_api ina230_emul_api_i2c = {
.transfer = ina230_emul_transfer_i2c,
};
#define INA230_EMUL(n) \
static const struct ina230_emul_cfg ina230_emul_cfg_##n = { \
.addr = DT_INST_REG_ADDR(n), \
}; \
static struct ina230_emul_data ina230_emul_data_##n = { \
.ina230_regs = { \
/* clang-format off */
#define CREATE_INA230_REGS \
{INA230_REG_CONFIG, 2, 0x4127}, \
{INA230_REG_SHUNT_VOLT, 2, 0}, \
{INA230_REG_BUS_VOLT, 2, 0}, \
@ -164,9 +166,30 @@ static const struct i2c_emul_api ina230_emul_api_i2c = {
{INA230_REG_CURRENT, 2, 0}, \
{INA230_REG_CALIB, 2, 0}, \
{INA230_REG_MASK, 2, 0}, \
{INA230_REG_ALERT, 2, 0}, \
}}; \
EMUL_DT_INST_DEFINE(n, ina230_emul_init, &ina230_emul_data_##n, &ina230_emul_cfg_##n, \
&ina230_emul_api_i2c, NULL)
{INA230_REG_ALERT, 2, 0}
DT_INST_FOREACH_STATUS_OKAY(INA230_EMUL)
#define CREATE_INA236_REGS \
CREATE_INA230_REGS, \
{INA236_REG_MANUFACTURER_ID, 2, 0x449}, \
{INA236_REG_DEVICE_ID, 2, 0xa080}
/* clang-format on */
#define INA230_EMUL(n, v) \
static const struct ina230_emul_cfg ina23##v##_emul_cfg_##n = { \
.addr = DT_INST_REG_ADDR(n), \
}; \
static struct ina230_reg ina23##v##_regs_##n[] = {CREATE_INA23##v##_REGS, {}}; \
static struct ina230_emul_data ina23##v##_emul_data_##n = { \
.regs = (struct ina230_reg *)ina23##v##_regs_##n, \
}; \
EMUL_DT_INST_DEFINE(n, ina230_emul_init, &ina23##v##_emul_data_##n, \
&ina23##v##_emul_cfg_##n, &ina230_emul_api_i2c, NULL)
#undef DT_DRV_COMPAT
#define DT_DRV_COMPAT ti_ina230
DT_INST_FOREACH_STATUS_OKAY_VARGS(INA230_EMUL, 0)
#undef DT_DRV_COMPAT
#define DT_DRV_COMPAT ti_ina236
DT_INST_FOREACH_STATUS_OKAY_VARGS(INA230_EMUL, 6)

View file

@ -9,6 +9,7 @@
#define INA230_EMUL_H_
#define INA230_REGISTER_COUNT 8
#define INA236_REGISTER_COUNT 2
int ina230_mock_set_register(void *data_ptr, int reg, uint32_t value);
int ina230_mock_get_register(void *data_ptr, int reg, uint32_t *value_ptr);

View file

@ -14,12 +14,18 @@
#include <ina230_emul.h>
#include <ina230.h>
enum ina23x_ids {
INA230,
INA236
};
struct ina230_fixture {
const struct device *dev;
const struct emul *mock;
const uint16_t current_lsb_uA;
const uint16_t rshunt_uOhms;
const uint16_t config;
const enum ina23x_ids dev_type;
};
/**
@ -44,6 +50,7 @@ ZTEST(ina230_0, test_default_config)
static void test_datasheet_example(struct ina230_fixture *fixture)
{
struct sensor_value sensor_val;
uint16_t raw_voltage, raw_current, raw_power;
double actual;
/* only run test for datasheet example of 1mA current LSB and 2 mOhm shunt */
@ -51,9 +58,19 @@ static void test_datasheet_example(struct ina230_fixture *fixture)
ztest_test_skip();
}
ina230_mock_set_register(fixture->mock->data, INA230_REG_BUS_VOLT, 9584);
ina230_mock_set_register(fixture->mock->data, INA230_REG_CURRENT, 10000);
ina230_mock_set_register(fixture->mock->data, INA230_REG_POWER, 4792);
if (fixture->dev_type == INA230) {
raw_voltage = 9584;
raw_current = 10000;
raw_power = 4792;
} else {
raw_voltage = 7487;
raw_current = 10000;
raw_power = 3744;
}
ina230_mock_set_register(fixture->mock->data, INA230_REG_BUS_VOLT, raw_voltage);
ina230_mock_set_register(fixture->mock->data, INA230_REG_CURRENT, raw_current);
ina230_mock_set_register(fixture->mock->data, INA230_REG_POWER, raw_power);
zassert_ok(sensor_sample_fetch(fixture->dev));
zassert_ok(sensor_channel_get(fixture->dev, SENSOR_CHAN_VOLTAGE, &sensor_val));
@ -136,6 +153,8 @@ static void test_bus_voltage(struct ina230_fixture *fixture)
0,
};
double bitres = fixture->dev_type == INA236 ? 1.6e-3 : 1.25e-3;
for (int idx = 0; idx < ARRAY_SIZE(voltage_reg_vectors); idx++) {
struct sensor_value sensor_val;
@ -147,7 +166,7 @@ static void test_bus_voltage(struct ina230_fixture *fixture)
zassert_ok(sensor_channel_get(fixture->dev, SENSOR_CHAN_VOLTAGE, &sensor_val));
double voltage_actual_V = sensor_value_to_double(&sensor_val);
double voltage_expected_V = voltage_reg_vectors[idx] * 1.25e-3;
double voltage_expected_V = voltage_reg_vectors[idx] * bitres;
zexpect_within(voltage_expected_V, voltage_actual_V, 1e-6,
"Expected %.6f A, got %.6f A", voltage_expected_V, voltage_actual_V);
@ -167,12 +186,14 @@ static void test_power(struct ina230_fixture *fixture)
0,
};
int scale = fixture->dev_type == INA236 ? 32 : 25;
for (int idx = 0; idx < ARRAY_SIZE(power_reg_vectors); idx++) {
struct sensor_value sensor_val;
uint32_t power_register = power_reg_vectors[idx];
/* power is power_register * 25 * current_lsb */
double power_expected_W = power_register * 25 * fixture->current_lsb_uA * 1e-6;
/* power is power_register * SCALE * current_lsb */
double power_expected_W = power_register * scale * fixture->current_lsb_uA * 1e-6;
/* set current reading */
ina230_mock_set_register(fixture->mock->data, INA230_REG_POWER, power_register);
@ -183,33 +204,51 @@ static void test_power(struct ina230_fixture *fixture)
double power_actual_W = sensor_value_to_double(&sensor_val);
zexpect_within(power_expected_W, power_actual_W, 1e-6,
"Expected %.6f W, got %.6f W for %d",
power_expected_W, power_actual_W, power_register);
"Expected %.6f W, got %.6f W for %d", power_expected_W,
power_actual_W, power_register);
}
}
/* Create a test fixture for each enabled ina230 device node */
#define DT_DRV_COMPAT ti_ina230
#define INA230_FIXTURE_ENTRY(inst) \
{ \
#define INA230_FIXTURE_ENTRY(inst, v) \
static struct ina230_fixture fixture_23##v##_##inst = { \
.dev = DEVICE_DT_INST_GET(inst), \
.mock = EMUL_DT_GET(DT_DRV_INST(inst)), \
.current_lsb_uA = DT_INST_PROP(inst, current_lsb_microamps), \
.rshunt_uOhms = DT_INST_PROP(inst, rshunt_micro_ohms), \
.config = DT_INST_PROP(inst, config), \
},
static struct ina230_fixture fixtures[] = {
DT_INST_FOREACH_STATUS_OKAY(INA230_FIXTURE_ENTRY)
};
.dev_type = INA23##v, \
}
/* Create a test suite for each enabled ina230 device node */
#define INA230_TESTS(inst) \
ZTEST(ina230_##inst, test_datasheet_example) { test_datasheet_example(&fixtures[inst]); } \
ZTEST(ina230_##inst, test_shunt_cal) { test_shunt_cal(&fixtures[inst]); } \
ZTEST(ina230_##inst, test_current) { test_current(&fixtures[inst]); } \
ZTEST(ina230_##inst, test_bus_voltage) { test_bus_voltage(&fixtures[inst]); } \
ZTEST(ina230_##inst, test_power) { test_power(&fixtures[inst]); } \
ZTEST_SUITE(ina230_##inst, NULL, NULL, NULL, NULL, NULL);
#define INA230_TESTS(inst, v) \
INA230_FIXTURE_ENTRY(inst, v); \
ZTEST(ina23##v##_##inst, test_datasheet_example) \
{ \
test_datasheet_example(&fixture_23##v##_##inst); \
} \
ZTEST(ina23##v##_##inst, test_shunt_cal) \
{ \
test_shunt_cal(&fixture_23##v##_##inst); \
} \
ZTEST(ina23##v##_##inst, test_current) \
{ \
test_current(&fixture_23##v##_##inst); \
} \
ZTEST(ina23##v##_##inst, test_bus_voltage) \
{ \
test_bus_voltage(&fixture_23##v##_##inst); \
} \
ZTEST(ina23##v##_##inst, test_power) \
{ \
test_power(&fixture_23##v##_##inst); \
} \
ZTEST_SUITE(ina23##v##_##inst, NULL, NULL, NULL, NULL, NULL);
DT_INST_FOREACH_STATUS_OKAY(INA230_TESTS)
#undef DT_DRV_COMPAT
#define DT_DRV_COMPAT ti_ina230
DT_INST_FOREACH_STATUS_OKAY_VARGS(INA230_TESTS, 0)
#undef DT_DRV_COMPAT
#define DT_DRV_COMPAT ti_ina236
DT_INST_FOREACH_STATUS_OKAY_VARGS(INA230_TESTS, 6)