emul: Add SBS Gauge emulator backend_api
In order to support easier setup of test scenarios with fuel gauge emulators, we should expose an API that can change internal emulator state. Add a minimal fuel gauge emulator backend API for setting the charging current and voltage with a sample implementation in the emul_sbs_gauge with an associated driver test. Signed-off-by: Aaron Massey <aaronmassey@google.com>
This commit is contained in:
parent
40924edec2
commit
e1401fcf5e
4 changed files with 138 additions and 3 deletions
|
@ -35,3 +35,4 @@ API Reference
|
|||
*************
|
||||
|
||||
.. doxygengroup:: fuel_gauge_interface
|
||||
.. doxygengroup:: fuel_gauge_emulator_backend
|
||||
|
|
|
@ -21,6 +21,7 @@ LOG_MODULE_REGISTER(sbs_sbs_gauge);
|
|||
#include <zephyr/drivers/i2c.h>
|
||||
#include <zephyr/drivers/i2c_emul.h>
|
||||
#include <zephyr/sys/byteorder.h>
|
||||
#include <zephyr/drivers/emul_fuel_gauge.h>
|
||||
#include <zephyr/drivers/fuel_gauge.h>
|
||||
|
||||
#include "sbs_gauge.h"
|
||||
|
@ -32,6 +33,13 @@ struct sbs_gauge_emul_data {
|
|||
uint16_t remaining_time_alarm;
|
||||
uint16_t mode;
|
||||
int16_t at_rate;
|
||||
struct {
|
||||
/* Non-register values associated with the state of the battery */
|
||||
/* Battery terminal voltage */
|
||||
uint32_t uV;
|
||||
/* Battery terminal current - Pos is charging, Neg is discharging */
|
||||
int uA;
|
||||
} batt_state;
|
||||
};
|
||||
|
||||
/** Static configuration for the emulator */
|
||||
|
@ -90,6 +98,11 @@ static int emul_sbs_gauge_reg_read(const struct emul *target, int reg, int *val)
|
|||
*val = data->at_rate;
|
||||
break;
|
||||
case SBS_GAUGE_CMD_VOLTAGE:
|
||||
*val = data->batt_state.uV / 1000;
|
||||
break;
|
||||
case SBS_GAUGE_CMD_CURRENT:
|
||||
*val = data->batt_state.uA / 1000;
|
||||
break;
|
||||
case SBS_GAUGE_CMD_AVG_CURRENT:
|
||||
case SBS_GAUGE_CMD_TEMP:
|
||||
case SBS_GAUGE_CMD_ASOC:
|
||||
|
@ -102,7 +115,6 @@ static int emul_sbs_gauge_reg_read(const struct emul *target, int reg, int *val)
|
|||
case SBS_GAUGE_CMD_RUNTIME2EMPTY:
|
||||
case SBS_GAUGE_CMD_CYCLE_COUNT:
|
||||
case SBS_GAUGE_CMD_DESIGN_VOLTAGE:
|
||||
case SBS_GAUGE_CMD_CURRENT:
|
||||
case SBS_GAUGE_CMD_CHG_CURRENT:
|
||||
case SBS_GAUGE_CMD_CHG_VOLTAGE:
|
||||
case SBS_GAUGE_CMD_FLAGS:
|
||||
|
@ -220,6 +232,23 @@ static int sbs_gauge_emul_transfer_i2c(const struct emul *target, struct i2c_msg
|
|||
return rc;
|
||||
}
|
||||
|
||||
static int emul_sbs_fuel_gauge_set_battery_charging(const struct emul *target, uint32_t uV, int uA)
|
||||
{
|
||||
struct sbs_gauge_emul_data *data = target->data;
|
||||
|
||||
if (uV == 0 || uA == 0)
|
||||
return -EINVAL;
|
||||
|
||||
data->batt_state.uA = uA;
|
||||
data->batt_state.uV = uV;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static const struct fuel_gauge_emul_driver_api sbs_gauge_backend_api = {
|
||||
.set_battery_charging = emul_sbs_fuel_gauge_set_battery_charging,
|
||||
};
|
||||
|
||||
static const struct i2c_emul_api sbs_gauge_emul_api_i2c = {
|
||||
.transfer = sbs_gauge_emul_transfer_i2c,
|
||||
};
|
||||
|
@ -243,11 +272,12 @@ static int emul_sbs_sbs_gauge_init(const struct emul *target, const struct devic
|
|||
* Main instantiation macro. SBS Gauge Emulator only implemented for I2C
|
||||
*/
|
||||
#define SBS_GAUGE_EMUL(n) \
|
||||
static struct sbs_gauge_emul_data sbs_gauge_emul_data_##n; \
|
||||
static struct sbs_gauge_emul_data sbs_gauge_emul_data_##n; \
|
||||
static const struct sbs_gauge_emul_cfg sbs_gauge_emul_cfg_##n = { \
|
||||
.addr = DT_INST_REG_ADDR(n), \
|
||||
}; \
|
||||
EMUL_DT_INST_DEFINE(n, emul_sbs_sbs_gauge_init, &sbs_gauge_emul_data_##n, \
|
||||
&sbs_gauge_emul_cfg_##n, &sbs_gauge_emul_api_i2c, NULL)
|
||||
&sbs_gauge_emul_cfg_##n, &sbs_gauge_emul_api_i2c, \
|
||||
&sbs_gauge_backend_api)
|
||||
|
||||
DT_INST_FOREACH_STATUS_OKAY(SBS_GAUGE_EMUL)
|
||||
|
|
73
include/zephyr/drivers/emul_fuel_gauge.h
Normal file
73
include/zephyr/drivers/emul_fuel_gauge.h
Normal file
|
@ -0,0 +1,73 @@
|
|||
/*
|
||||
* Copyright (c) 2023 Google LLC
|
||||
*
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
*/
|
||||
|
||||
/**
|
||||
* @file
|
||||
* @brief Backend APIs for the fuel gauge emulators.
|
||||
*/
|
||||
|
||||
#ifndef ZEPHYR_INCLUDE_DRIVERS_EMUL_FUEL_GAUGE_H_
|
||||
#define ZEPHYR_INCLUDE_DRIVERS_EMUL_FUEL_GAUGE_H_
|
||||
|
||||
#include <stdint.h>
|
||||
#include <zephyr/drivers/emul.h>
|
||||
#include <zephyr/drivers/fuel_gauge.h>
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
/**
|
||||
* @brief Fuel gauge backend emulator APIs
|
||||
* @defgroup fuel_gauge_emulator_backend fuel gauge backed emulator APIs
|
||||
* @ingroup io_interfaces
|
||||
* @{
|
||||
*/
|
||||
|
||||
/**
|
||||
* @cond INTERNAL_HIDDEN
|
||||
*
|
||||
* These are for internal use only, so skip these in public documentation.
|
||||
*/
|
||||
__subsystem struct fuel_gauge_emul_driver_api {
|
||||
int (*set_battery_charging)(const struct emul *emul, uint32_t uV, int uA);
|
||||
};
|
||||
/**
|
||||
* @endcond
|
||||
*/
|
||||
|
||||
/**
|
||||
* @brief Set charging for fuel gauge associated battery.
|
||||
*
|
||||
* Set how much the battery associated with a fuel gauge IC is charging or discharging. Where
|
||||
* voltage is always positive and a positive or negative current denotes charging or discharging,
|
||||
* respectively.
|
||||
*
|
||||
* @param target Pointer to the emulator structure for the fuel gauge emulator instance.
|
||||
* @param uV Microvolts describing the battery voltage.
|
||||
* @param uA Microamps describing the battery current where negative is discharging.
|
||||
*
|
||||
* @retval 0 If successful.
|
||||
* @retval -EINVAL if mV or mA are 0.
|
||||
*/
|
||||
static inline int emul_fuel_gauge_set_battery_charging(const struct emul *target, uint32_t uV,
|
||||
int uA)
|
||||
{
|
||||
const struct fuel_gauge_emul_driver_api *backend_api =
|
||||
(const struct fuel_gauge_emul_driver_api *)target->backend_api;
|
||||
|
||||
return backend_api->set_battery_charging(target, uV, uA);
|
||||
}
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
/**
|
||||
* @}
|
||||
*/
|
||||
|
||||
#endif /* ZEPHYR_INCLUDE_DRIVERS_EMUL_FUEL_GAUGE_H_*/
|
|
@ -6,6 +6,8 @@
|
|||
*/
|
||||
|
||||
#include <zephyr/device.h>
|
||||
#include <zephyr/drivers/emul.h>
|
||||
#include <zephyr/drivers/emul_fuel_gauge.h>
|
||||
#include <zephyr/drivers/fuel_gauge.h>
|
||||
#include <zephyr/drivers/i2c.h>
|
||||
#include <zephyr/logging/log.h>
|
||||
|
@ -16,6 +18,7 @@
|
|||
|
||||
struct sbs_gauge_new_api_fixture {
|
||||
const struct device *dev;
|
||||
const struct emul *sbs_fuel_gauge;
|
||||
const struct fuel_gauge_driver_api *api;
|
||||
};
|
||||
|
||||
|
@ -24,6 +27,7 @@ static void *sbs_gauge_new_api_setup(void)
|
|||
static ZTEST_DMEM struct sbs_gauge_new_api_fixture fixture;
|
||||
|
||||
fixture.dev = DEVICE_DT_GET_ANY(sbs_sbs_gauge_new_api);
|
||||
fixture.sbs_fuel_gauge = EMUL_DT_GET(DT_NODELABEL(smartbattery0));
|
||||
|
||||
k_object_access_all_grant(fixture.dev);
|
||||
|
||||
|
@ -344,5 +348,32 @@ ZTEST_USER_F(sbs_gauge_new_api, test_get_buffer_props__returns_ok)
|
|||
zassert_ok(ret);
|
||||
}
|
||||
|
||||
ZTEST_F(sbs_gauge_new_api, test_charging_5v_3a)
|
||||
{
|
||||
/* Validate what props are supported by the driver */
|
||||
uint32_t expected_uV = 5000 * 1000;
|
||||
uint32_t expected_uA = 3000 * 1000;
|
||||
|
||||
struct fuel_gauge_get_property props[] = {
|
||||
{
|
||||
.property_type = FUEL_GAUGE_VOLTAGE,
|
||||
},
|
||||
{
|
||||
.property_type = FUEL_GAUGE_CURRENT,
|
||||
},
|
||||
};
|
||||
|
||||
zassume_ok(emul_fuel_gauge_set_battery_charging(fixture->sbs_fuel_gauge, expected_uV,
|
||||
expected_uA));
|
||||
zassert_ok(fuel_gauge_get_prop(fixture->dev, props, ARRAY_SIZE(props)));
|
||||
|
||||
zassert_ok(props[0].status);
|
||||
zassert_equal(props[0].value.voltage, expected_uV, "Got %d instead of %d",
|
||||
props[0].value.voltage, expected_uV);
|
||||
|
||||
zassert_ok(props[1].status);
|
||||
zassert_equal(props[1].value.current, expected_uA, "Got %d instead of %d",
|
||||
props[1].value.current, expected_uA);
|
||||
}
|
||||
|
||||
ZTEST_SUITE(sbs_gauge_new_api, NULL, sbs_gauge_new_api_setup, NULL, NULL, NULL);
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue