Cover the shunt-, bus- and die-temperature injection properties and the current and power values derived through the Shunt Calibration register, including the zero-calibration case, the ADCRANGE rescaling and the clamp/overflow edges.
Signed-off-by: Emmanuel Blot <[email protected]> --- tests/qtest/ina238-test.c | 156 ++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 156 insertions(+) diff --git a/tests/qtest/ina238-test.c b/tests/qtest/ina238-test.c index 6e59ed30b5..693139f988 100644 --- a/tests/qtest/ina238-test.c +++ b/tests/qtest/ina238-test.c @@ -89,6 +89,20 @@ static void qmp_ina238_set(const char *property, int value) qobject_unref(resp); } +static int qmp_ina238_get(const char *property) +{ + QDict *resp; + int ret; + + resp = qmp("{ 'execute': 'qom-get', 'arguments':" + " { 'path': %s, 'property': %s } }", + INA238_TEST_ID, property); + g_assert(qdict_haskey(resp, "return")); + ret = qdict_get_int(resp, "return"); + qobject_unref(resp); + return ret; +} + /* Power-on-reset default values and the ID registers */ static void test_defaults(void *obj, void *data, QGuestAllocator *alloc) { @@ -160,6 +174,139 @@ static void test_config_wmask(void *obj, void *data, QGuestAllocator *alloc) g_assert_cmphex(i2c_get16(dev, REG_CONFIG), ==, CONFIG_POR); } +/* Shunt voltage register */ +static void test_shunt_injection(void *obj, void *data, QGuestAllocator *alloc) +{ + QI2CDevice *dev = (QI2CDevice *)obj; + + i2c_set16(dev, REG_CONFIG, CONFIG_RST); + + qmp_ina238_set("shunt-voltage", 97200000); + g_assert_cmphex(i2c_get16(dev, REG_VSHUNT), ==, 0x4BF0); + + qmp_ina238_set("shunt-voltage", -80000000); + g_assert_cmphex(i2c_get16(dev, REG_VSHUNT), ==, 0xC180); + + g_assert_cmpint(qmp_ina238_get("shunt-voltage"), ==, -80000000); +} + +/* Bus voltage register */ +static void test_bus_injection(void *obj, void *data, QGuestAllocator *alloc) +{ + QI2CDevice *dev = (QI2CDevice *)obj; + + i2c_set16(dev, REG_CONFIG, CONFIG_RST); + + qmp_ina238_set("bus-voltage", 48000000); + g_assert_cmphex(i2c_get16(dev, REG_VBUS), ==, 0x3C00); + + qmp_ina238_set("bus-voltage", 12000000); + g_assert_cmphex(i2c_get16(dev, REG_VBUS), ==, 0x0F00); +} + +/* Die temperature register */ +static void test_temp_injection(void *obj, void *data, QGuestAllocator *alloc) +{ + QI2CDevice *dev = (QI2CDevice *)obj; + + i2c_set16(dev, REG_CONFIG, CONFIG_RST); + + qmp_ina238_set("die-temperature", 25000); + g_assert_cmphex(i2c_get16(dev, REG_DIETEMP), ==, 0x0C80); + + qmp_ina238_set("die-temperature", -25000); + g_assert_cmphex(i2c_get16(dev, REG_DIETEMP), ==, 0xF380); + + g_assert_cmpint(qmp_ina238_get("die-temperature"), ==, -25000); +} + +/* Calibration-derived current */ +static void test_calibration_current(void *obj, void *data, + QGuestAllocator *alloc) +{ + QI2CDevice *dev = (QI2CDevice *)obj; + + i2c_set16(dev, REG_CONFIG, CONFIG_RST); + qmp_ina238_set("shunt-voltage", 97200000); + + i2c_set16(dev, REG_SHUNT_CAL, 0x0000); + g_assert_cmphex(i2c_get16(dev, REG_CURRENT), ==, 0x0000); + + i2c_set16(dev, REG_SHUNT_CAL, 0x0FD2); + g_assert_cmphex(i2c_get16(dev, REG_CURRENT), ==, 0x4CCC); +} + +/* Calibration-derived power */ +static void test_power(void *obj, void *data, QGuestAllocator *alloc) +{ + QI2CDevice *dev = (QI2CDevice *)obj; + + i2c_set16(dev, REG_CONFIG, CONFIG_RST); + qmp_ina238_set("shunt-voltage", 97200000); + qmp_ina238_set("bus-voltage", 48000000); + i2c_set16(dev, REG_SHUNT_CAL, 0x0FD2); + + g_assert_cmpuint(i2c_get24(dev, REG_POWER), ==, 4718400); +} + +/* With SHUNT_CAL == 0 the current and power registers stay zero */ +static void test_zero_cal(void *obj, void *data, QGuestAllocator *alloc) +{ + QI2CDevice *dev = (QI2CDevice *)obj; + + i2c_set16(dev, REG_CONFIG, CONFIG_RST); + i2c_set16(dev, REG_SHUNT_CAL, 0x0000); + qmp_ina238_set("shunt-voltage", 97200000); + qmp_ina238_set("bus-voltage", 48000000); + + g_assert_cmphex(i2c_get16(dev, REG_CURRENT), ==, 0x0000); + g_assert_cmpuint(i2c_get24(dev, REG_POWER), ==, 0); +} + +/* ADCRANGE changes the shunt LSB, not the current divisor. */ +static void test_adcrange(void *obj, void *data, QGuestAllocator *alloc) +{ + QI2CDevice *dev = (QI2CDevice *)obj; + + i2c_set16(dev, REG_CONFIG, CONFIG_RST); + + qmp_ina238_set("shunt-voltage", 20000000); + g_assert_cmphex(i2c_get16(dev, REG_VSHUNT), ==, 0x0FA0); + + i2c_set16(dev, REG_SHUNT_CAL, 0x0800); + g_assert_cmphex(i2c_get16(dev, REG_CURRENT), ==, 0x1F40); + + i2c_set16(dev, REG_CONFIG, CONFIG_ADCRANGE); + g_assert_cmphex(i2c_get16(dev, REG_VSHUNT), ==, 0x3E80); + + g_assert_cmphex(i2c_get16(dev, REG_CURRENT), ==, 0x7D00); + + i2c_set16(dev, REG_SHUNT_CAL, 0x2000); + g_assert_cmphex(i2c_get16(dev, REG_CURRENT), ==, 0x1F40); +} + +/* Clamping at full scale and the MATHOF flag */ +static void test_overflow(void *obj, void *data, QGuestAllocator *alloc) +{ + QI2CDevice *dev = (QI2CDevice *)obj; + + i2c_set16(dev, REG_CONFIG, CONFIG_RST); + + i2c_set16(dev, REG_CONFIG, CONFIG_ADCRANGE); + qmp_ina238_set("shunt-voltage", 97200000); + g_assert_cmphex(i2c_get16(dev, REG_VSHUNT), ==, 0x7FFF); + qmp_ina238_set("shunt-voltage", -97200000); + g_assert_cmphex(i2c_get16(dev, REG_VSHUNT), ==, 0x8000); + + i2c_set16(dev, REG_CONFIG, CONFIG_POR); + qmp_ina238_set("shunt-voltage", 163835000); + i2c_set16(dev, REG_SHUNT_CAL, 0x0001); + g_assert_cmphex(i2c_get16(dev, REG_CURRENT), ==, 0x7FFF); + g_assert_cmphex(i2c_get16(dev, REG_DIAG_ALRT) & DIAG_MATHOF, ==, + DIAG_MATHOF); +} + +/* Shunt over-limit alert (transparent mode) */ static void ina238_register_nodes(void) { QOSGraphEdgeOptions opts = { @@ -173,5 +320,14 @@ static void ina238_register_nodes(void) qos_add_test("defaults", "ina238", test_defaults, NULL); qos_add_test("soft-reset", "ina238", test_soft_reset, NULL); qos_add_test("config-wmask", "ina238", test_config_wmask, NULL); + qos_add_test("shunt-injection", "ina238", test_shunt_injection, NULL); + qos_add_test("bus-injection", "ina238", test_bus_injection, NULL); + qos_add_test("temp-injection", "ina238", test_temp_injection, NULL); + qos_add_test("calibration-current", "ina238", test_calibration_current, + NULL); + qos_add_test("power", "ina238", test_power, NULL); + qos_add_test("zero-cal", "ina238", test_zero_cal, NULL); + qos_add_test("adcrange", "ina238", test_adcrange, NULL); + qos_add_test("overflow", "ina238", test_overflow, NULL); } libqos_init(ina238_register_nodes); -- 2.50.1
