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:
parent
3602342611
commit
953436b185
4 changed files with 123 additions and 52 deletions
|
@ -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";
|
||||
};
|
||||
};
|
||||
|
|
|
@ -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)
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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)
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue