tests: adltc2990: introduce mock_i2c_error function

Introduce mock_i2c_error function in emulator in order to emulate i2c
errors for various registers

Signed-off-by: Jilay Pandya <jilay.pandya@outlook.com>
This commit is contained in:
Jilay Pandya 2025-03-02 19:13:15 +01:00 committed by Dan Kalowsky
parent 529029e4e3
commit 6cc35eea81
4 changed files with 231 additions and 36 deletions

View File

@ -1,6 +1,6 @@
/*
* SPDX-FileCopyrightText: Copyright (c) 2025 Jilay Sandeep Pandya
* SPDX-FileCopyrightText: Copyright (c) 2023 Carl Zeiss Meditec AG
* SPDX-FileCopyrightText: Copyright (c) 2024 Jilay Sandeep Pandya
* SPDX-License-Identifier: Apache-2.0
*/
@ -151,7 +151,7 @@ int adltc2990_trigger_measurement(const struct device *dev,
return -EIO;
}
WRITE_BIT(ctrl_reg_setting, ADLTC2990_ACQUISTION_BIT_POS, format);
WRITE_BIT(ctrl_reg_setting, ADLTC2990_ACQUISITION_BIT_POS, format);
if (i2c_reg_write_byte_dt(&cfg->bus, ADLTC2990_REG_CONTROL, ctrl_reg_setting)) {
LOG_ERR("configuring for single bus failed.");
@ -242,35 +242,6 @@ static int adltc2990_fetch_property_value(const struct device *dev,
return 0;
}
static int adltc2990_init(const struct device *dev)
{
const struct adltc2990_config *cfg = dev->config;
struct adltc2990_data *data = dev->data;
int err;
if (!i2c_is_ready_dt(&cfg->bus)) {
LOG_ERR("I2C bus %s not ready", cfg->bus.bus->name);
return -ENODEV;
}
const uint8_t ctrl_reg_setting = cfg->temp_format << 7 | data->acq_format << 6 | 0 << 5 |
cfg->measurement_mode[1] << 3 | cfg->measurement_mode[0];
LOG_DBG("Setting Control Register to: 0x%x", ctrl_reg_setting);
if (i2c_reg_write_byte_dt(&cfg->bus, ADLTC2990_REG_CONTROL, ctrl_reg_setting)) {
LOG_ERR("configuring for single bus failed.");
return -EIO;
}
err = adltc2990_trigger_measurement(dev, data->acq_format);
if (err < 0) {
LOG_ERR("triggering measurement failed: %d", err);
}
LOG_INF("Initializing ADLTC2990 with name %s", dev->name);
return 0;
}
static int fetch_pin_differential_voltage_value(const struct device *dev,
const enum adltc2990_monitoring_type mode,
const enum adltc2990_monitor_pins pin)
@ -618,6 +589,35 @@ static int adltc2990_channel_get(const struct device *dev, enum sensor_channel c
return 0;
}
static int adltc2990_init(const struct device *dev)
{
const struct adltc2990_config *cfg = dev->config;
struct adltc2990_data *data = dev->data;
int err;
if (!i2c_is_ready_dt(&cfg->bus)) {
LOG_ERR("I2C bus %s not ready", cfg->bus.bus->name);
return -ENODEV;
}
const uint8_t ctrl_reg_setting = cfg->temp_format << 7 | data->acq_format << 6 | 0 << 5 |
cfg->measurement_mode[1] << 3 | cfg->measurement_mode[0];
LOG_DBG("Setting Control Register to: 0x%x", ctrl_reg_setting);
if (i2c_reg_write_byte_dt(&cfg->bus, ADLTC2990_REG_CONTROL, ctrl_reg_setting)) {
LOG_ERR("configuring for single bus failed.");
return -EIO;
}
err = adltc2990_trigger_measurement(dev, data->acq_format);
if (err < 0) {
LOG_ERR("triggering measurement failed: %d", err);
}
LOG_INF("Initializing ADLTC2990 with name %s", dev->name);
return 0;
}
static DEVICE_API(sensor, adltc2990_driver_api) = {
.sample_fetch = adltc2990_sample_fetch,
.channel_get = adltc2990_channel_get,

View File

@ -1,6 +1,6 @@
/*
* SPDX-FileCopyrightText: Copyright (c) 2025 Jilay Sandeep Pandya
* SPDX-FileCopyrightText: Copyright (c) 2023 Carl Zeiss Meditec AG
* SPDX-FileCopyrightText: Copyright (c) 2024 Jilay Sandeep Pandya
* SPDX-License-Identifier: Apache-2.0
*/
@ -23,6 +23,7 @@ LOG_MODULE_DECLARE(adltc2990, CONFIG_SENSOR_LOG_LEVEL);
#define ADLTC2990_NUM_REGS ADLTC2990_REG_VCC_LSB
struct adltc2990_emul_data {
uint8_t mock_i2c_reg_error;
uint8_t reg[ADLTC2990_NUM_REGS];
};
@ -49,6 +50,7 @@ void adltc2990_emul_reset(const struct emul *target)
{
struct adltc2990_emul_data *data = target->data;
data->mock_i2c_reg_error = ADLTC2990_NUM_REGS + 1;
memset(data->reg, 0, ADLTC2990_NUM_REGS);
}
@ -75,6 +77,7 @@ static int adltc2990_emul_transfer_i2c(const struct emul *target, struct i2c_msg
int num_msgs, int addr)
{
struct adltc2990_emul_data *data = target->data;
uint8_t regn = msgs->buf[0];
i2c_dump_msgs_rw(target->dev, msgs, num_msgs, addr, false);
@ -91,7 +94,6 @@ static int adltc2990_emul_transfer_i2c(const struct emul *target, struct i2c_msg
return -EIO;
}
uint8_t regn = msgs->buf[0];
bool is_read = FIELD_GET(I2C_MSG_READ, msgs->flags) == 1;
bool is_stop = FIELD_GET(I2C_MSG_STOP, msgs->flags) == 1;

View File

@ -53,9 +53,9 @@
#define ADLTC2990_TEMPERATURE_FORMAT_CELSIUS 0U
#define ADLTC2990_TEMPERATURE_FORMAT_KELVIN 1U
#define ADLTC2990_ACQUISTION_BIT_POS 6U
#define ADLTC2990_ACQUISTION_BIT_MSK BIT(ADLTC2990_ACQUISTION_BIT_POS)
#define ADLTC2990_ACQUISITION_BIT_POS 6U
#define ADLTC2990_ACQUISITION_BIT_MSK BIT(ADLTC2990_ACQUISITION_BIT_POS)
#define ADLTC2990_ACQUISITION_BIT_VAL(reg) \
((reg) & ADLTC2990_ACQUISTION_BIT_MSK) >> ADLTC2990_ACQUISTION_BIT_POS
((reg) & ADLTC2990_ACQUISITION_BIT_MSK) >> ADLTC2990_ACQUISITION_BIT_POS
#endif /* ZEPHYR_DRIVERS_SENSOR_ADLTC2990_REG_H */

View File

@ -5,15 +5,61 @@
*/
#include <zephyr/devicetree.h>
#include <zephyr/drivers/emul_sensor.h>
#include <zephyr/drivers/emul.h>
#include <zephyr/drivers/i2c_emul.h>
#include <zephyr/drivers/sensor.h>
#include <zephyr/drivers/sensor/adltc2990.h>
#include <zephyr/fff.h>
#include <zephyr/ztest.h>
#include "adltc2990_emul.h"
#include "adltc2990_reg.h"
#include "adltc2990_internal.h"
#include <zephyr/logging/log.h>
DEFINE_FFF_GLOBALS;
DECLARE_FAKE_VALUE_FUNC(int, fake_mock_i2c_transfer, uint8_t, int, int);
DEFINE_FAKE_VALUE_FUNC(int, fake_mock_i2c_transfer, uint8_t, int, int);
static int mock_i2c_transfer_fail_reg_number = -1;
static int adltc2990_i2c_is_touching_reg_delegate(uint8_t start_reg, int num_msgs, int reg)
{
if (start_reg == reg) {
return -EIO;
}
return 0;
}
static int mock_i2c_transfer_delegate(const struct emul *target, struct i2c_msg *msgs, int num_msgs,
int addr)
{
ARG_UNUSED(target);
ARG_UNUSED(addr);
uint8_t start_reg = msgs[0].buf[0];
fake_mock_i2c_transfer_fake.return_val =
fake_mock_i2c_transfer(start_reg, num_msgs, mock_i2c_transfer_fail_reg_number);
if (fake_mock_i2c_transfer_fake.return_val == -EIO) {
return -EIO;
}
return -ENOSYS;
}
static void reset_mock_i2c_transfer_fake(void)
{
mock_i2c_transfer_fail_reg_number = -1;
fake_mock_i2c_transfer_reset();
fake_mock_i2c_transfer_fake.custom_fake = adltc2990_i2c_is_touching_reg_delegate;
}
/* Colllection of common assertion macros */
#define CHECK_SINGLE_ENDED_VOLTAGE(sensor_val, index, pin_voltage, r1, r2) \
zassert_ok(sensor_sample_fetch_chan(fixture->dev, SENSOR_CHAN_VOLTAGE)); \
@ -119,6 +165,65 @@ static void adltc2990_4_3_before(void *f)
ZTEST_SUITE(adltc2990_4_3, NULL, adltc2990_4_3_setup, adltc2990_4_3_before, NULL, NULL);
ZTEST_F(adltc2990_4_3, test_mock_i2c_error)
{
struct i2c_emul_api mock_bus_api;
fixture->target->bus.i2c->mock_api = &mock_bus_api;
mock_bus_api.transfer = mock_i2c_transfer_delegate;
reset_mock_i2c_transfer_fake();
mock_i2c_transfer_fail_reg_number = ADLTC2990_REG_STATUS;
bool is_busy;
zassert_equal(-EIO, adltc2990_is_busy(fixture->dev, &is_busy), "I2C Error not detected");
zassert_equal(1, fake_mock_i2c_transfer_fake.call_count);
reset_mock_i2c_transfer_fake();
mock_i2c_transfer_fail_reg_number = ADLTC2990_REG_TRIGGER;
adltc2990_trigger_measurement(fixture->dev, ADLTC2990_REPEATED_ACQUISITION);
zassert_equal(-EIO, fake_mock_i2c_transfer_fake.return_val);
reset_mock_i2c_transfer_fake();
mock_i2c_transfer_fail_reg_number = ADLTC2990_REG_CONTROL;
adltc2990_trigger_measurement(fixture->dev, ADLTC2990_SINGLE_SHOT_ACQUISITION);
zassert_equal(ADLTC2990_REG_CONTROL, fake_mock_i2c_transfer_fake.arg0_val);
zassert_equal(-EIO, fake_mock_i2c_transfer_fake.return_val);
reset_mock_i2c_transfer_fake();
mock_i2c_transfer_fail_reg_number = ADLTC2990_REG_VCC_LSB;
zassert_equal(-EIO, sensor_sample_fetch_chan(fixture->dev, SENSOR_CHAN_VOLTAGE));
zassert_equal(ADLTC2990_REG_VCC_LSB, fake_mock_i2c_transfer_fake.arg0_val);
reset_mock_i2c_transfer_fake();
mock_i2c_transfer_fail_reg_number = ADLTC2990_REG_V1_MSB;
zassert_equal(-EIO, sensor_sample_fetch_chan(fixture->dev, SENSOR_CHAN_AMBIENT_TEMP));
zassert_equal(-EIO, fake_mock_i2c_transfer_fake.return_val);
reset_mock_i2c_transfer_fake();
mock_i2c_transfer_fail_reg_number = ADLTC2990_REG_V3_MSB;
zassert_equal(-EIO, sensor_sample_fetch_chan(fixture->dev, SENSOR_CHAN_CURRENT));
zassert_equal(-EIO, fake_mock_i2c_transfer_fake.return_val);
reset_mock_i2c_transfer_fake();
mock_i2c_transfer_fail_reg_number = ADLTC2990_REG_INTERNAL_TEMP_MSB;
zassert_equal(-EIO, sensor_sample_fetch_chan(fixture->dev, SENSOR_CHAN_DIE_TEMP));
zassert_equal(1, fake_mock_i2c_transfer_fake.call_count);
reset_mock_i2c_transfer_fake();
mock_i2c_transfer_fail_reg_number = ADLTC2990_REG_V1_MSB;
zassert_equal(-EIO, sensor_sample_fetch_chan(fixture->dev, SENSOR_CHAN_AMBIENT_TEMP));
zassert_equal(1, fake_mock_i2c_transfer_fake.call_count);
}
ZTEST_F(adltc2990_4_3, test_available_channels)
{
struct sensor_value value[3];
@ -292,6 +397,20 @@ static void adltc2990_5_3_before(void *f)
ZTEST_SUITE(adltc2990_5_3, NULL, adltc2990_5_3_setup, adltc2990_5_3_before, NULL, NULL);
ZTEST_F(adltc2990_5_3, test_mock_i2c_error)
{
struct i2c_emul_api mock_bus_api;
fixture->target->bus.i2c->mock_api = &mock_bus_api;
mock_bus_api.transfer = mock_i2c_transfer_delegate;
reset_mock_i2c_transfer_fake();
mock_i2c_transfer_fail_reg_number = ADLTC2990_REG_V3_MSB;
zassert_equal(-EIO, sensor_sample_fetch_chan(fixture->dev, SENSOR_CHAN_AMBIENT_TEMP));
zassert_equal(3, fake_mock_i2c_transfer_fake.call_count);
}
ZTEST_F(adltc2990_5_3, test_ambient_temperature)
{
/*Kelvin 0b00010001 0b00010010 273.1250*/
@ -353,6 +472,39 @@ static void adltc2990_6_3_before(void *f)
ZTEST_SUITE(adltc2990_6_3, NULL, adltc2990_6_3_setup, adltc2990_6_3_before, NULL, NULL);
ZTEST_F(adltc2990_6_3, test_mock_i2c_error)
{
struct i2c_emul_api mock_bus_api;
fixture->target->bus.i2c->mock_api = &mock_bus_api;
mock_bus_api.transfer = mock_i2c_transfer_delegate;
reset_mock_i2c_transfer_fake();
mock_i2c_transfer_fail_reg_number = ADLTC2990_REG_VCC_LSB;
zassert_equal(-EIO, sensor_sample_fetch_chan(fixture->dev, SENSOR_CHAN_VOLTAGE));
zassert_equal(-EIO, fake_mock_i2c_transfer_fake.return_val);
zassert_equal(2, fake_mock_i2c_transfer_fake.call_count);
reset_mock_i2c_transfer_fake();
mock_i2c_transfer_fail_reg_number = ADLTC2990_REG_V1_MSB;
zassert_equal(-EIO, sensor_sample_fetch_chan(fixture->dev, SENSOR_CHAN_VOLTAGE));
zassert_equal(3, fake_mock_i2c_transfer_fake.call_count);
reset_mock_i2c_transfer_fake();
mock_i2c_transfer_fail_reg_number = ADLTC2990_REG_V3_MSB;
zassert_equal(-EIO, sensor_sample_fetch_chan(fixture->dev, SENSOR_CHAN_VOLTAGE));
zassert_equal(5, fake_mock_i2c_transfer_fake.call_count);
reset_mock_i2c_transfer_fake();
mock_i2c_transfer_fail_reg_number = ADLTC2990_REG_V1_LSB;
zassert_equal(-EIO, sensor_sample_fetch_chan(fixture->dev, SENSOR_CHAN_CURRENT));
zassert_equal(2, fake_mock_i2c_transfer_fake.call_count);
}
ZTEST_F(adltc2990_6_3, test_current)
{
/* 0b00111100 0b01011000 +0.300 */
@ -400,6 +552,47 @@ static void adltc2990_7_3_before(void *f)
ZTEST_SUITE(adltc2990_7_3, NULL, adltc2990_7_3_setup, adltc2990_7_3_before, NULL, NULL);
ZTEST_F(adltc2990_7_3, test_mock_i2c_error)
{
struct i2c_emul_api mock_bus_api;
fixture->target->bus.i2c->mock_api = &mock_bus_api;
mock_bus_api.transfer = mock_i2c_transfer_delegate;
reset_mock_i2c_transfer_fake();
mock_i2c_transfer_fail_reg_number = ADLTC2990_REG_VCC_LSB;
zassert_equal(-EIO, sensor_sample_fetch_chan(fixture->dev, SENSOR_CHAN_VOLTAGE));
zassert_equal(-EIO, fake_mock_i2c_transfer_fake.return_val);
zassert_equal(2, fake_mock_i2c_transfer_fake.call_count);
reset_mock_i2c_transfer_fake();
mock_i2c_transfer_fail_reg_number = ADLTC2990_REG_V1_MSB;
zassert_equal(-EIO, sensor_sample_fetch_chan(fixture->dev, SENSOR_CHAN_VOLTAGE));
zassert_equal(-EIO, fake_mock_i2c_transfer_fake.return_val);
zassert_equal(3, fake_mock_i2c_transfer_fake.call_count);
reset_mock_i2c_transfer_fake();
mock_i2c_transfer_fail_reg_number = ADLTC2990_REG_V2_MSB;
zassert_equal(-EIO, sensor_sample_fetch_chan(fixture->dev, SENSOR_CHAN_VOLTAGE));
zassert_equal(-EIO, fake_mock_i2c_transfer_fake.return_val);
zassert_equal(5, fake_mock_i2c_transfer_fake.call_count);
reset_mock_i2c_transfer_fake();
mock_i2c_transfer_fail_reg_number = ADLTC2990_REG_V3_MSB;
zassert_equal(-EIO, sensor_sample_fetch_chan(fixture->dev, SENSOR_CHAN_VOLTAGE));
zassert_equal(7, fake_mock_i2c_transfer_fake.call_count);
reset_mock_i2c_transfer_fake();
mock_i2c_transfer_fail_reg_number = ADLTC2990_REG_V4_MSB;
zassert_equal(-EIO, sensor_sample_fetch_chan(fixture->dev, SENSOR_CHAN_VOLTAGE));
zassert_equal(9, fake_mock_i2c_transfer_fake.call_count);
}
ZTEST_F(adltc2990_7_3, test_available_channels)
{
zassert_equal(-EINVAL, sensor_sample_fetch_chan(fixture->dev, SENSOR_CHAN_AMBIENT_TEMP));