diff --git a/Documentation/components/drivers/special/power/battery/fakegauge.rst b/Documentation/components/drivers/special/power/battery/fakegauge.rst new file mode 100644 index 00000000000..9859c7dbda1 --- /dev/null +++ b/Documentation/components/drivers/special/power/battery/fakegauge.rst @@ -0,0 +1,67 @@ +=============== + Battery Gauge +=============== + +Battery gauge driver for NuttX that measurement battery data (voltage, +current, capacity, temperature, and charging status) for charger and +healthd in production. + +Fake Gauge +========== + +A fake battery gauge driver for NuttX that simulates battery data (voltage, +current, capacity, temperature, and charging status) for testing and +development purposes. it provides mock battery data without requiring physical +battery hardware.It generates random values within predefined ranges and +updates them periodically, making it useful for: + + - Testing battery monitoring applications + - Developing power management features + - Debugging battery-related logic without real hardware + +Features +======== + +The Fake gauge simulates key battery parameters. + + Voltage (mV): + - Voltage ranges: 4000mV to 4200mV + + Current (mA): + - Current ranges: -100mA to 500mA + - Current resolution: 1mA + + Capacity (%): + - Capacity ranges: 0% to 100% + - Capacity resolution: 1% + + Temperature (0.1°C): + - Temperature resolution: 0.1°C + + Charging Status: + - Charging + - Discharging + - Not charging + + Periodic data updates (default: 5 seconds) + Compatible with NuttX battery gauge framework. + + +Usage +===== + + File Information + - Path: drivers/power/battery/battery_fakegauge.c + - License: Apache License 2.0 + + Dependencies + - NuttX operating system + - NuttX battery gauge framework (nuttx/power/battery_gauge.h) + - NuttX work queue for periodic updates + + Configuration + - Enable the fake gauge driver in the NuttX configuration file (CONFIG_BATTERY_FAKEGAUGE=y) + - Configure the update interval in seconds (CONFIG_BATTERY_FAKEGAUGE_UPDATE_INTERVAL) + +This driver is intended for development and testing only, not for production use with +real batteries. diff --git a/Documentation/components/drivers/special/power/index.rst b/Documentation/components/drivers/special/power/index.rst index 956088be163..f08cf486502 100644 --- a/Documentation/components/drivers/special/power/index.rst +++ b/Documentation/components/drivers/special/power/index.rst @@ -6,3 +6,4 @@ Power-related Drivers :caption: Supported Drivers pm/index.rst + battery/fakegauge.rst diff --git a/drivers/power/battery/CMakeLists.txt b/drivers/power/battery/CMakeLists.txt index 311bdd3e0ce..b3dffd47588 100644 --- a/drivers/power/battery/CMakeLists.txt +++ b/drivers/power/battery/CMakeLists.txt @@ -92,4 +92,8 @@ if(CONFIG_GOLDFISH_BATTERY) list(APPEND SRCS goldfish_battery.c) endif() +if(CONFIG_BATTERY_FAKE_GAUGE) + list(APPEND SRCS battery_fakegauge.c) +endif() + target_sources(drivers PRIVATE ${SRCS}) diff --git a/drivers/power/battery/Kconfig b/drivers/power/battery/Kconfig index 07de5b4b0fd..0e8cb107209 100644 --- a/drivers/power/battery/Kconfig +++ b/drivers/power/battery/Kconfig @@ -160,4 +160,11 @@ config GOLDFISH_BATTERY ---help--- The GOLDFISH_BATTERY are battery charger for emulate batteries. +config BATTERY_FAKE_GAUGE + bool "Battery fake gauge support" + default n + depends on BATTERY_GAUGE + ---help--- + The BATTERY FAKE are battery charger for emulate gauge. + endmenu diff --git a/drivers/power/battery/Make.defs b/drivers/power/battery/Make.defs index 419384a2bd3..26a05cca308 100644 --- a/drivers/power/battery/Make.defs +++ b/drivers/power/battery/Make.defs @@ -90,5 +90,9 @@ ifeq ($(CONFIG_GOLDFISH_BATTERY),y) CSRCS += goldfish_battery.c endif +ifeq ($(CONFIG_BATTERY_FAKE_GAUGE),y) +CSRCS += battery_fakegauge.c +endif + DEPPATH += --dep-path power/battery VPATH += power/battery diff --git a/drivers/power/battery/battery_fakegauge.c b/drivers/power/battery/battery_fakegauge.c new file mode 100644 index 00000000000..91d08ed4056 --- /dev/null +++ b/drivers/power/battery/battery_fakegauge.c @@ -0,0 +1,286 @@ +/**************************************************************************** + * drivers/power/battery/battery_fakegauge.c + * + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. The + * ASF licenses this file to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance with the + * License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT + * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the + * License for the specific language governing permissions and limitations + * under the License. + * + ****************************************************************************/ + +/**************************************************************************** + * Included Files + ****************************************************************************/ + +#include +#include +#include + +#include +#include +#include +#include +#include +#include +#include + +/**************************************************************************** + * Pre-processor Definitions + ****************************************************************************/ + +#define BATTERY_FAKE_VOLTAGE_MAX (4200) +#define BATTERY_FAKE_VOLTAGE_MIN (4000) +#define BATTERY_FAKE_CURRENT_MAX (500) +#define BATTERY_FAKE_CURRENT_MIN (100) +#define BATTERY_FAKE_CAPACITY_MAX (100) +#define BATTERY_FAKE_CAPACITY_MIN (60) // we dont want too lower +#define BATTERY_FAKE_TEMP_MAX (420) +#define BATTERY_FAKE_TEMP_MIN (220) +#define BATTERY_FAKE_WORK_DELAY MSEC2TICK(5000) +#define BATTERY_FAKE_GAUGE "/dev/charge/fakegauge" + +/**************************************************************************** + * Private type + ****************************************************************************/ + +struct battery_fake_data_s +{ + uint32_t present; + uint32_t voltage; + uint32_t capacity; + uint32_t current; + uint32_t temperature; + uint32_t status; +}; + +struct battery_fake_gauge_s +{ + struct battery_gauge_dev_s battery; + struct battery_fake_data_s data; + struct work_s poll_work; +}; + +/**************************************************************************** + * Private Function Prototypes + ****************************************************************************/ + +static int battery_fake_present(FAR struct battery_gauge_dev_s *dev, + FAR bool *status); +static int battery_fake_state(FAR struct battery_gauge_dev_s *dev, + FAR int *status); +static int battery_fake_voltage(FAR struct battery_gauge_dev_s *dev, + FAR int *value); +static int battery_fake_capacity(FAR struct battery_gauge_dev_s *dev, + FAR int *value); +static int battery_fake_current(FAR struct battery_gauge_dev_s *dev, + FAR int *value); +static int battery_fake_temperature(FAR struct battery_gauge_dev_s *dev, + FAR int *value); + +/**************************************************************************** + * Private Data + ****************************************************************************/ + +static const struct battery_gauge_operations_s g_battery_fake_ops = +{ + battery_fake_state, + battery_fake_present, + battery_fake_voltage, + battery_fake_capacity, + battery_fake_current, + battery_fake_temperature, + NULL, +}; + +/**************************************************************************** + * Private Functions + ****************************************************************************/ + +static int battery_fake_present(FAR struct battery_gauge_dev_s *dev, + FAR bool *status) +{ + /* fake gauge is always keep present */ + + *status = true; + + return OK; +} + +static int battery_fake_state(FAR struct battery_gauge_dev_s *dev, + FAR int *status) +{ + FAR struct battery_fake_gauge_s *priv = + container_of(dev, struct battery_fake_gauge_s, battery); + + *status = priv->data.status; + return OK; +} + +static int battery_fake_voltage(FAR struct battery_gauge_dev_s *dev, + FAR int *value) +{ + FAR struct battery_fake_gauge_s *priv = + container_of(dev, struct battery_fake_gauge_s, battery); + + *value = priv->data.voltage; + return OK; +} + +static int battery_fake_capacity(FAR struct battery_gauge_dev_s *dev, + FAR int *value) +{ + FAR struct battery_fake_gauge_s *priv = + container_of(dev, struct battery_fake_gauge_s, battery); + + *value = priv->data.capacity; + return OK; +} + +static int battery_fake_current(FAR struct battery_gauge_dev_s *dev, + FAR int *value) +{ + FAR struct battery_fake_gauge_s *priv = + container_of(dev, struct battery_fake_gauge_s, battery); + + *value = priv->data.current; + return OK; +} + +static int battery_fake_temperature(FAR struct battery_gauge_dev_s *dev, + FAR int *value) +{ + FAR struct battery_fake_gauge_s *priv = + container_of(dev, struct battery_fake_gauge_s, battery); + + *value = priv->data.temperature; + return OK; +} + +static void battery_fake_data_init(FAR struct battery_fake_data_s *data) +{ + data->status = BATTERY_CHARGING; + data->capacity = BATTERY_FAKE_CAPACITY_MIN; + data->temperature = BATTERY_FAKE_TEMP_MIN; + data->voltage = BATTERY_FAKE_VOLTAGE_MIN; + data->current = BATTERY_FAKE_CURRENT_MIN; + data->present = true; +} + +static int battery_fake_data_charged(FAR struct battery_fake_gauge_s *priv) +{ + FAR struct battery_fake_data_s *data = &priv->data; + int capacity; + int voltage; + int current; + int temp; + int ret; + + /* capacity */ + + capacity = BATTERY_FAKE_CAPACITY_MIN + + rand() % (BATTERY_FAKE_CAPACITY_MAX - BATTERY_FAKE_CAPACITY_MIN + 1); + data->capacity = capacity; + + /* voltage */ + + voltage = BATTERY_FAKE_VOLTAGE_MIN + + rand() % (BATTERY_FAKE_VOLTAGE_MAX - BATTERY_FAKE_VOLTAGE_MIN + 1); + data->voltage = voltage; + + /* current */ + + current = BATTERY_FAKE_CURRENT_MIN + + rand() % (BATTERY_FAKE_CURRENT_MAX - BATTERY_FAKE_CURRENT_MIN + 1); + data->current = current; + + /* temperature */ + + temp = BATTERY_FAKE_TEMP_MIN + + rand() % (BATTERY_FAKE_TEMP_MAX - BATTERY_FAKE_TEMP_MIN + 1); + data->temperature = temp; + + if (data->capacity > 10 && data->capacity < 95) + { + data->status = BATTERY_CHARGING; + } + else if (data->capacity >= 100) + { + data->status = BATTERY_DISCHARGING; + data->current = 0; + } + else if (data->capacity >= 95 && data->capacity < 100) + { + data->status = BATTERY_FULL; + } + else + { + data->status = BATTERY_UNKNOWN; + } + + ret = battery_gauge_changed(&priv->battery, BATTERY_STATE_CHANGED | + BATTERY_VOLTAGE_CHANGED | + BATTERY_CURRENT_CHANGED | + BATTERY_CAPACITY_CHANGED | + BATTERY_TEMPERATURE_CHANGED); + if (ret < 0) + { + baterr("battery fake gauge changed failed %d\n", ret); + } + + return ret; +} + +static void battery_fake_work(FAR void *arg) +{ + FAR struct battery_fake_gauge_s *priv = + (FAR struct battery_fake_gauge_s *)arg; + + battery_fake_data_charged(priv); + + work_queue(LPWORK, &priv->poll_work, battery_fake_work, priv, + BATTERY_FAKE_WORK_DELAY); +} + +/**************************************************************************** + * Public Functions + ****************************************************************************/ + +int battery_fake_gauge_register() +{ + int ret; + FAR struct battery_fake_gauge_s *priv; + + priv = kmm_zalloc(sizeof(struct battery_fake_gauge_s)); + if (NULL == priv) + { + baterr(" no enough memory\n"); + return -ENOMEM; + } + + battery_fake_data_init(&priv->data); + + priv->battery.ops = &g_battery_fake_ops; + ret = battery_gauge_register(BATTERY_FAKE_GAUGE, &priv->battery); + if (ret < 0) + { + baterr("battery_gauge_register %s failed\n", BATTERY_FAKE_GAUGE); + kmm_free(priv); + return ret; + } + + work_queue(LPWORK, &priv->poll_work, battery_fake_work, priv, + BATTERY_FAKE_WORK_DELAY); + + batinfo("battery fake gauge register successfully\n"); + return 0; +} diff --git a/include/nuttx/power/battery_gauge.h b/include/nuttx/power/battery_gauge.h index 0501410f564..5548e15eb44 100644 --- a/include/nuttx/power/battery_gauge.h +++ b/include/nuttx/power/battery_gauge.h @@ -277,6 +277,21 @@ FAR struct battery_gauge_dev_s *max1704x_initialize( int goldfish_battery_register(FAR void *regs, int irq); #endif +#if defined(CONFIG_BATTERY_FAKE_GAUGE) +/**************************************************************************** + * Name: battery_fake_gauge_register + * Description: + * Register a emulate battery to the upper-half gauge driver. + * + * Returned Value: + * Zero on success or a negated errno value on failure. + * + * + ****************************************************************************/ + +int battery_fake_gauge_register(void); +#endif + #undef EXTERN #ifdef __cplusplus }