Browse Source

samples: fuelgauge: unify fuel gauge sample

Replace IC specific fuel gauge example with a generic fuel gauge example
and move the fuel gauge sample to sample/drivers folder

Signed-off-by: Philipp Steiner <philipp.steiner1987@gmail.com>
pull/92275/head
Philipp Steiner 1 month ago committed by Daniel DeGrasse
parent
commit
67211341ca
  1. 1
      boards/adafruit/feather_esp32s2/adafruit_feather_esp32s2_tft_reverse.dts
  2. 1
      boards/adafruit/feather_esp32s3/adafruit_feather_esp32s3_procpu.dts
  3. 1
      boards/adafruit/feather_esp32s3_tft/adafruit_feather_esp32s3_tft_procpu.dts
  4. 2
      samples/drivers/fuel_gauge/CMakeLists.txt
  5. 86
      samples/drivers/fuel_gauge/README.rst
  6. 0
      samples/drivers/fuel_gauge/boards/adafruit_feather_esp32s2.conf
  7. 22
      samples/drivers/fuel_gauge/boards/adafruit_feather_esp32s2_B.overlay
  8. 20
      samples/drivers/fuel_gauge/boards/adafruit_feather_esp32s2_C.overlay
  9. 0
      samples/drivers/fuel_gauge/boards/adafruit_feather_esp32s2_tft.conf
  10. 22
      samples/drivers/fuel_gauge/boards/adafruit_feather_esp32s2_tft.overlay
  11. 0
      samples/drivers/fuel_gauge/boards/adafruit_feather_esp32s2_tft_reverse.conf
  12. 11
      samples/drivers/fuel_gauge/boards/adafruit_feather_esp32s2_tft_reverse.overlay
  13. 0
      samples/drivers/fuel_gauge/boards/adafruit_feather_esp32s3_procpu.conf
  14. 6
      samples/drivers/fuel_gauge/boards/nrf52840dk_nrf52840.overlay
  15. 4
      samples/drivers/fuel_gauge/prj.conf
  16. 20
      samples/drivers/fuel_gauge/sample.yaml
  17. 379
      samples/drivers/fuel_gauge/src/main.c
  18. 5
      samples/fuel_gauge/fuel_gauge.rst
  19. 51
      samples/fuel_gauge/max17048/README.rst
  20. 8
      samples/fuel_gauge/max17048/boards/adafruit_feather_esp32s2_C.overlay
  21. 8
      samples/fuel_gauge/max17048/boards/adafruit_feather_esp32s2_tft.overlay
  22. 1
      samples/fuel_gauge/max17048/prj.conf
  23. 9
      samples/fuel_gauge/max17048/sample.yaml
  24. 67
      samples/fuel_gauge/max17048/src/main.c

1
boards/adafruit/feather_esp32s2/adafruit_feather_esp32s2_tft_reverse.dts

@ -19,6 +19,7 @@ @@ -19,6 +19,7 @@
aliases {
backlight = &led1;
fuel-gauge0 = &max17048;
};
leds {

1
boards/adafruit/feather_esp32s3/adafruit_feather_esp32s3_procpu.dts

@ -38,6 +38,7 @@ @@ -38,6 +38,7 @@
sw0 = &button0;
led0 = &led0;
led-strip = &led_strip;
fuel-gauge0 = &max17048;
};
buttons {

1
boards/adafruit/feather_esp32s3_tft/adafruit_feather_esp32s3_tft_procpu.dts

@ -22,6 +22,7 @@ @@ -22,6 +22,7 @@
aliases {
i2c-0 = &i2c0;
watchdog0 = &wdt0;
fuel-gauge0 = &max17048;
};
chosen {

2
samples/fuel_gauge/max17048/CMakeLists.txt → samples/drivers/fuel_gauge/CMakeLists.txt

@ -2,7 +2,7 @@ @@ -2,7 +2,7 @@
cmake_minimum_required(VERSION 3.20.0)
find_package(Zephyr REQUIRED HINTS $ENV{ZEPHYR_BASE})
project(max17048)
project(fuel_gauge)
FILE(GLOB app_sources src/*.c)
target_sources(app PRIVATE ${app_sources})

86
samples/drivers/fuel_gauge/README.rst

@ -0,0 +1,86 @@ @@ -0,0 +1,86 @@
.. zephyr:code-sample:: fuel_gauge
:name: Fuel Gauge
Use fuel gauge API to access fuel gauge properties and get charge information.
Overview
********
This sample shows how to use the Zephyr :ref:`fuel_gauge_api` API driver for.
First, the sample tries to read all public fuel gauge properties to verify which are supported by
the used fuel gauge driver.
Second, the sample then reads the battery percentage and voltage proper periodically using the
``FUEL_GAUGE_RELATIVE_STATE_OF_CHARGE`` and ``FUEL_GAUGE_VOLTAGE`` properties.
.. note::
The sample does not set/write any properties to avoid misconfiguration the IC.
Building and Running
********************
The sample can be configured to support a fuel gauge.
Features
********
By using this fuel gauge you can get the following information:
* Read all public fuel gauge properties except ``FUEL_GAUGE_BATTERY_CUTOFF``
* Battery charge status as percentage (periodically)
* Battery voltage (periodically)
Sample output
*************
.. code-block:: console
*** Booting Zephyr OS build f95fd665ad26 ***
[00:00:00.116,000] <inf> app: Found device "lc709203f@0b"
[00:00:00.116,000] <inf> app: Test-Read generic fuel gauge properties to verify which are supported
[00:00:00.116,000] <inf> app: Info: not all properties are supported by all fuel gauges!
[00:00:00.116,000] <inf> app: Property "FUEL_GAUGE_AVG_CURRENT" is not supported
[00:00:00.116,000] <inf> app: Property "FUEL_GAUGE_CURRENT" is not supported
[00:00:00.116,000] <inf> app: Property "FUEL_GAUGE_CHARGE_CUTOFF" is not supported
[00:00:00.116,000] <inf> app: Property "FUEL_GAUGE_CYCLE_COUNT" is not supported
[00:00:00.116,000] <inf> app: Property "FUEL_GAUGE_CONNECT_STATE" is not supported
[00:00:00.116,000] <inf> app: Property "FUEL_GAUGE_FLAGS" is not supported
[00:00:00.116,000] <inf> app: Property "FUEL_GAUGE_FULL_CHARGE_CAPACITY" is not supported
[00:00:00.116,000] <inf> app: Property "FUEL_GAUGE_PRESENT_STATE" is not supported
[00:00:00.116,000] <inf> app: Property "FUEL_GAUGE_REMAINING_CAPACITY" is not supported
[00:00:00.116,000] <inf> app: Property "FUEL_GAUGE_RUNTIME_TO_EMPTY" is not supported
[00:00:00.116,000] <inf> app: Property "FUEL_GAUGE_RUNTIME_TO_FULL" is not supported
[00:00:00.116,000] <inf> app: Property "FUEL_GAUGE_SBS_MFR_ACCESS" is not supported
[00:00:00.116,000] <inf> app: Property "FUEL_GAUGE_ABSOLUTE_STATE_OF_CHARGE" is not supported
[00:00:00.122,000] <inf> app: Property "FUEL_GAUGE_RELATIVE_STATE_OF_CHARGE" is supported
[00:00:00.122,000] <inf> app: Relative state of charge: 100
[00:00:00.122,000] <err> lc709203f: Thermistor not enabled
[00:00:00.122,000] <inf> app: Property "FUEL_GAUGE_TEMPERATURE" is not supported
[00:00:00.123,000] <inf> app: Property "FUEL_GAUGE_VOLTAGE" is supported
[00:00:00.123,000] <inf> app: Voltage: 4190000
[00:00:00.124,000] <inf> app: Property "FUEL_GAUGE_SBS_MODE" is supported
[00:00:00.124,000] <inf> app: SBS mode: 1
[00:00:00.124,000] <inf> app: Property "FUEL_GAUGE_CHARGE_CURRENT" is not supported
[00:00:00.124,000] <inf> app: Property "FUEL_GAUGE_CHARGE_VOLTAGE" is not supported
[00:00:00.124,000] <inf> app: Property "FUEL_GAUGE_STATUS" is not supported
[00:00:00.124,000] <inf> app: Property "FUEL_GAUGE_DESIGN_CAPACITY" is supported
[00:00:00.124,000] <inf> app: Design capacity: 500
[00:00:00.124,000] <inf> app: Property "FUEL_GAUGE_DESIGN_VOLTAGE" is not supported
[00:00:00.124,000] <inf> app: Property "FUEL_GAUGE_SBS_ATRATE" is not supported
[00:00:00.124,000] <inf> app: Property "FUEL_GAUGE_SBS_ATRATE_TIME_TO_FULL" is not supported
[00:00:00.124,000] <inf> app: Property "FUEL_GAUGE_SBS_ATRATE_TIME_TO_EMPTY" is not supported
[00:00:00.124,000] <inf> app: Property "FUEL_GAUGE_SBS_ATRATE_OK" is not supported
[00:00:00.125,000] <inf> app: Property "FUEL_GAUGE_SBS_REMAINING_CAPACITY_ALARM" is not supported
[00:00:00.125,000] <inf> app: Property "FUEL_GAUGE_SBS_REMAINING_TIME_ALARM" is not supported
[00:00:00.125,000] <err> app: Error: cannot get property "FUEL_GAUGE_MANUFACTURER_NAME": -88
[00:00:00.125,000] <err> app: Error: cannot get property "FUEL_GAUGE_DEVICE_NAME": -88
[00:00:00.125,000] <err> app: Error: cannot get property "FUEL_GAUGE_DEVICE_CHEMISTRY": -88
[00:00:00.125,000] <inf> app: Property "FUEL_GAUGE_CURRENT_DIRECTION" is supported
[00:00:00.125,000] <inf> app: Current direction: 0
[00:00:00.126,000] <inf> app: Property "FUEL_GAUGE_STATE_OF_CHARGE_ALARM" is supported
[00:00:00.126,000] <inf> app: State of charge alarm: 8
[00:00:00.127,000] <inf> app: Property "FUEL_GAUGE_LOW_VOLTAGE_ALARM" is supported
[00:00:00.127,000] <inf> app: Low voltage alarm: 0
[00:00:00.127,000] <inf> app: Polling fuel gauge data 'FUEL_GAUGE_RELATIVE_STATE_OF_CHARGE' & 'FUEL_GAUGE_VOLTAGE'
[00:00:00.128,000] <inf> app: Fuel gauge data: Charge: 100%, Voltage: 4190mV
[00:00:05.130,000] <inf> app: Fuel gauge data: Charge: 100%, Voltage: 4190mV
[00:00:10.131,000] <inf> app: Fuel gauge data: Charge: 100%, Voltage: 4190mV

0
samples/fuel_gauge/max17048/boards/adafruit_feather_esp32s2_C.conf → samples/drivers/fuel_gauge/boards/adafruit_feather_esp32s2.conf

22
samples/drivers/fuel_gauge/boards/adafruit_feather_esp32s2_B.overlay

@ -0,0 +1,22 @@ @@ -0,0 +1,22 @@
/*
* Copyright (c) 2025 Philipp Steiner <philipp.steiner1987@gmail.com>
*
* SPDX-License-Identifier: Apache-2.0
*/
/ {
aliases {
fuel-gauge0 = &lc709203f;
};
};
&i2c0 {
lc709203f: lc709203f@0b {
compatible = "onnn,lc709203f";
status = "okay";
reg = <0x0b>;
power-domains = <&i2c_reg>;
apa = "500mAh";
battery-profile = <0x01>;
};
};

20
samples/drivers/fuel_gauge/boards/adafruit_feather_esp32s2_C.overlay

@ -0,0 +1,20 @@ @@ -0,0 +1,20 @@
/*
* Copyright (c) 2025 Philipp Steiner <philipp.steiner1987@gmail.com>
*
* SPDX-License-Identifier: Apache-2.0
*/
/ {
aliases {
fuel-gauge0 = &max17048;
};
};
&i2c0 {
max17048: max17048@36 {
compatible = "maxim,max17048";
status = "okay";
reg = <0x36 >;
power-domains = <&i2c_reg>;
};
};

0
samples/fuel_gauge/max17048/boards/adafruit_feather_esp32s2_tft.conf → samples/drivers/fuel_gauge/boards/adafruit_feather_esp32s2_tft.conf

22
samples/drivers/fuel_gauge/boards/adafruit_feather_esp32s2_tft.overlay

@ -0,0 +1,22 @@ @@ -0,0 +1,22 @@
/*
* Copyright (c) 2025 Philipp Steiner <philipp.steiner1987@gmail.com>
*
* SPDX-License-Identifier: Apache-2.0
*/
/ {
aliases {
fuel-gauge0 = &lc709203f;
};
};
&i2c0 {
lc709203f: lc709203f@0b {
compatible = "onnn,lc709203f";
status = "okay";
reg = <0x0b>;
power-domains = <&i2c_reg>;
apa = "500mAh";
battery-profile = <0x01>;
};
};

0
samples/fuel_gauge/max17048/boards/adafruit_feather_esp32s2_tft_reverse.conf → samples/drivers/fuel_gauge/boards/adafruit_feather_esp32s2_tft_reverse.conf

11
samples/drivers/fuel_gauge/boards/adafruit_feather_esp32s2_tft_reverse.overlay

@ -0,0 +1,11 @@ @@ -0,0 +1,11 @@
/*
* Copyright (c) 2025 Philipp Steiner <philipp.steiner1987@gmail.com>
*
* SPDX-License-Identifier: Apache-2.0
*/
&i2c0 {
max17048: max17048@36 {
status = "okay";
};
};

0
samples/fuel_gauge/max17048/boards/adafruit_feather_esp32s3_procpu.conf → samples/drivers/fuel_gauge/boards/adafruit_feather_esp32s3_procpu.conf

6
samples/fuel_gauge/max17048/boards/nrf52840dk_nrf52840.overlay → samples/drivers/fuel_gauge/boards/nrf52840dk_nrf52840.overlay

@ -4,6 +4,12 @@ @@ -4,6 +4,12 @@
* SPDX-License-Identifier: Apache-2.0
*/
/ {
aliases {
fuel-gauge0 = &max17048;
};
};
&i2c0 {
status = "okay";
compatible = "nordic,nrf-twim";

4
samples/drivers/fuel_gauge/prj.conf

@ -0,0 +1,4 @@ @@ -0,0 +1,4 @@
CONFIG_FUEL_GAUGE=y
CONFIG_I2C=y
CONFIG_LOG=y
CONFIG_LOG_BUFFER_SIZE=4096

20
samples/drivers/fuel_gauge/sample.yaml

@ -0,0 +1,20 @@ @@ -0,0 +1,20 @@
sample:
name: Fuel Gauge Sensor Sample
tests:
sample.sensor.fuel_gauge:
build_only: true
platform_allow:
- nrf52840dk/nrf52840
- adafruit_feather_esp32s2@B
- adafruit_feather_esp32s2@C
- adafruit_feather_esp32s2_tft
- adafruit_feather_esp32s2_tft_reverse/esp32s2
- adafruit_feather_esp32s3/esp32s3/procpu
integration_platforms:
- nrf52840dk/nrf52840
- adafruit_feather_esp32s2@B
- adafruit_feather_esp32s2@C
- adafruit_feather_esp32s2_tft
- adafruit_feather_esp32s2_tft_reverse/esp32s2
- adafruit_feather_esp32s3/esp32s3/procpu
tags: fuel_gauge

379
samples/drivers/fuel_gauge/src/main.c

@ -0,0 +1,379 @@ @@ -0,0 +1,379 @@
/*
* Copyright (c) 2023 Alvaro Garcia Gomez <maxpowel@gmail.com>
* Copyright (c) 2025 Philipp Steiner <philipp.steiner1987@gmail.com>
*
* SPDX-License-Identifier: Apache-2.0
*/
#include "zephyr/sys/util.h"
#include <zephyr/kernel.h>
#include <zephyr/device.h>
#include <zephyr/devicetree.h>
#include <zephyr/drivers/fuel_gauge.h>
#define LOG_LEVEL CONFIG_LOG_DEFAULT_LEVEL
#include <zephyr/logging/log.h>
LOG_MODULE_REGISTER(app);
const char *fuel_gauge_prop_to_str(enum fuel_gauge_prop_type prop)
{
switch (prop) {
case FUEL_GAUGE_AVG_CURRENT:
return "FUEL_GAUGE_AVG_CURRENT";
case FUEL_GAUGE_BATTERY_CUTOFF:
return "FUEL_GAUGE_BATTERY_CUTOFF";
case FUEL_GAUGE_CURRENT:
return "FUEL_GAUGE_CURRENT";
case FUEL_GAUGE_CHARGE_CUTOFF:
return "FUEL_GAUGE_CHARGE_CUTOFF";
case FUEL_GAUGE_CYCLE_COUNT:
return "FUEL_GAUGE_CYCLE_COUNT";
case FUEL_GAUGE_CONNECT_STATE:
return "FUEL_GAUGE_CONNECT_STATE";
case FUEL_GAUGE_FLAGS:
return "FUEL_GAUGE_FLAGS";
case FUEL_GAUGE_FULL_CHARGE_CAPACITY:
return "FUEL_GAUGE_FULL_CHARGE_CAPACITY";
case FUEL_GAUGE_PRESENT_STATE:
return "FUEL_GAUGE_PRESENT_STATE";
case FUEL_GAUGE_REMAINING_CAPACITY:
return "FUEL_GAUGE_REMAINING_CAPACITY";
case FUEL_GAUGE_RUNTIME_TO_EMPTY:
return "FUEL_GAUGE_RUNTIME_TO_EMPTY";
case FUEL_GAUGE_RUNTIME_TO_FULL:
return "FUEL_GAUGE_RUNTIME_TO_FULL";
case FUEL_GAUGE_SBS_MFR_ACCESS:
return "FUEL_GAUGE_SBS_MFR_ACCESS";
case FUEL_GAUGE_ABSOLUTE_STATE_OF_CHARGE:
return "FUEL_GAUGE_ABSOLUTE_STATE_OF_CHARGE";
case FUEL_GAUGE_RELATIVE_STATE_OF_CHARGE:
return "FUEL_GAUGE_RELATIVE_STATE_OF_CHARGE";
case FUEL_GAUGE_TEMPERATURE:
return "FUEL_GAUGE_TEMPERATURE";
case FUEL_GAUGE_VOLTAGE:
return "FUEL_GAUGE_VOLTAGE";
case FUEL_GAUGE_SBS_MODE:
return "FUEL_GAUGE_SBS_MODE";
case FUEL_GAUGE_CHARGE_CURRENT:
return "FUEL_GAUGE_CHARGE_CURRENT";
case FUEL_GAUGE_CHARGE_VOLTAGE:
return "FUEL_GAUGE_CHARGE_VOLTAGE";
case FUEL_GAUGE_STATUS:
return "FUEL_GAUGE_STATUS";
case FUEL_GAUGE_DESIGN_CAPACITY:
return "FUEL_GAUGE_DESIGN_CAPACITY";
case FUEL_GAUGE_DESIGN_VOLTAGE:
return "FUEL_GAUGE_DESIGN_VOLTAGE";
case FUEL_GAUGE_SBS_ATRATE:
return "FUEL_GAUGE_SBS_ATRATE";
case FUEL_GAUGE_SBS_ATRATE_TIME_TO_FULL:
return "FUEL_GAUGE_SBS_ATRATE_TIME_TO_FULL";
case FUEL_GAUGE_SBS_ATRATE_TIME_TO_EMPTY:
return "FUEL_GAUGE_SBS_ATRATE_TIME_TO_EMPTY";
case FUEL_GAUGE_SBS_ATRATE_OK:
return "FUEL_GAUGE_SBS_ATRATE_OK";
case FUEL_GAUGE_SBS_REMAINING_CAPACITY_ALARM:
return "FUEL_GAUGE_SBS_REMAINING_CAPACITY_ALARM";
case FUEL_GAUGE_SBS_REMAINING_TIME_ALARM:
return "FUEL_GAUGE_SBS_REMAINING_TIME_ALARM";
case FUEL_GAUGE_MANUFACTURER_NAME:
return "FUEL_GAUGE_MANUFACTURER_NAME";
case FUEL_GAUGE_DEVICE_NAME:
return "FUEL_GAUGE_DEVICE_NAME";
case FUEL_GAUGE_DEVICE_CHEMISTRY:
return "FUEL_GAUGE_DEVICE_CHEMISTRY";
case FUEL_GAUGE_CURRENT_DIRECTION:
return "FUEL_GAUGE_CURRENT_DIRECTION";
case FUEL_GAUGE_STATE_OF_CHARGE_ALARM:
return "FUEL_GAUGE_STATE_OF_CHARGE_ALARM";
case FUEL_GAUGE_LOW_VOLTAGE_ALARM:
return "FUEL_GAUGE_LOW_VOLTAGE_ALARM";
default:
return "Unknown fuel gauge property";
}
}
int main(void)
{
const struct device *const dev = DEVICE_DT_GET(DT_ALIAS(fuel_gauge0));
int ret = 0;
if (dev == NULL) {
LOG_ERR("no device found.");
return 0;
}
if (!device_is_ready(dev)) {
LOG_ERR("Error: Device \"%s\" is not ready; check the driver initialization logs "
"for errors.",
dev->name);
return 0;
}
LOG_INF("Found device \"%s\"", dev->name);
{
LOG_INF("Test-Read generic fuel gauge properties to verify which are supported");
LOG_INF("Info: not all properties are supported by all fuel gauges!");
/*
* FUEL_GAUGE_BATTERY_CUTOFF will not be tested because this is a special property
* and is intended to be used to cutoff the battery from the system - useful for
* storage/shipping of devices
*/
fuel_gauge_prop_t test_props[] = {
FUEL_GAUGE_AVG_CURRENT,
FUEL_GAUGE_CURRENT,
FUEL_GAUGE_CHARGE_CUTOFF,
FUEL_GAUGE_CYCLE_COUNT,
FUEL_GAUGE_CONNECT_STATE,
FUEL_GAUGE_FLAGS,
FUEL_GAUGE_FULL_CHARGE_CAPACITY,
FUEL_GAUGE_PRESENT_STATE,
FUEL_GAUGE_REMAINING_CAPACITY,
FUEL_GAUGE_RUNTIME_TO_EMPTY,
FUEL_GAUGE_RUNTIME_TO_FULL,
FUEL_GAUGE_SBS_MFR_ACCESS,
FUEL_GAUGE_ABSOLUTE_STATE_OF_CHARGE,
FUEL_GAUGE_RELATIVE_STATE_OF_CHARGE,
FUEL_GAUGE_TEMPERATURE,
FUEL_GAUGE_VOLTAGE,
FUEL_GAUGE_SBS_MODE,
FUEL_GAUGE_CHARGE_CURRENT,
FUEL_GAUGE_CHARGE_VOLTAGE,
FUEL_GAUGE_STATUS,
FUEL_GAUGE_DESIGN_CAPACITY,
FUEL_GAUGE_DESIGN_VOLTAGE,
FUEL_GAUGE_SBS_ATRATE,
FUEL_GAUGE_SBS_ATRATE_TIME_TO_FULL,
FUEL_GAUGE_SBS_ATRATE_TIME_TO_EMPTY,
FUEL_GAUGE_SBS_ATRATE_OK,
FUEL_GAUGE_SBS_REMAINING_CAPACITY_ALARM,
FUEL_GAUGE_SBS_REMAINING_TIME_ALARM,
FUEL_GAUGE_MANUFACTURER_NAME,
FUEL_GAUGE_DEVICE_NAME,
FUEL_GAUGE_DEVICE_CHEMISTRY,
FUEL_GAUGE_CURRENT_DIRECTION,
FUEL_GAUGE_STATE_OF_CHARGE_ALARM,
FUEL_GAUGE_LOW_VOLTAGE_ALARM,
};
union fuel_gauge_prop_val test_vals[ARRAY_SIZE(test_props)];
for (size_t i = 0; i < ARRAY_SIZE(test_props); i++) {
if (test_props[i] == FUEL_GAUGE_MANUFACTURER_NAME) {
struct sbs_gauge_manufacturer_name mfg_name;
ret = fuel_gauge_get_buffer_prop(dev, FUEL_GAUGE_MANUFACTURER_NAME,
&mfg_name, sizeof(mfg_name));
if (ret == -ENOTSUP) {
LOG_INF("Property \"%s\" is not supported",
fuel_gauge_prop_to_str(test_props[i]));
} else if (ret < 0) {
LOG_ERR("Error: cannot get property \"%s\": %d",
fuel_gauge_prop_to_str(test_props[i]), ret);
} else {
LOG_INF("Property \"%s\" is supported",
fuel_gauge_prop_to_str(test_props[i]));
LOG_INF("Manufacturer name: %s",
mfg_name.manufacturer_name);
}
} else if (test_props[i] == FUEL_GAUGE_DEVICE_NAME) {
struct sbs_gauge_device_name dev_name;
ret = fuel_gauge_get_buffer_prop(dev, FUEL_GAUGE_DEVICE_NAME,
&dev_name, sizeof(dev_name));
if (ret == -ENOTSUP) {
LOG_INF("Property \"%s\" is not supported",
fuel_gauge_prop_to_str(test_props[i]));
} else if (ret < 0) {
LOG_ERR("Error: cannot get property \"%s\": %d",
fuel_gauge_prop_to_str(test_props[i]), ret);
} else {
LOG_INF("Property \"%s\" is supported",
fuel_gauge_prop_to_str(test_props[i]));
LOG_INF("Device name: %s", dev_name.device_name);
}
} else if (test_props[i] == FUEL_GAUGE_DEVICE_CHEMISTRY) {
struct sbs_gauge_device_chemistry device_chemistry;
ret = fuel_gauge_get_buffer_prop(dev, FUEL_GAUGE_DEVICE_CHEMISTRY,
&device_chemistry,
sizeof(device_chemistry));
if (ret == -ENOTSUP) {
LOG_INF("Property \"%s\" is not supported",
fuel_gauge_prop_to_str(test_props[i]));
} else if (ret < 0) {
LOG_ERR("Error: cannot get property \"%s\": %d",
fuel_gauge_prop_to_str(test_props[i]), ret);
} else {
LOG_INF("Property \"%s\" is supported",
fuel_gauge_prop_to_str(test_props[i]));
LOG_INF("Device chemistry: %s",
device_chemistry.device_chemistry);
}
} else {
/* For all other properties, use the generic get_props function */
ret = fuel_gauge_get_props(dev, &test_props[i], &test_vals[i], 1);
if (ret == -ENOTSUP) {
LOG_INF("Property \"%s\" is not supported",
fuel_gauge_prop_to_str(test_props[i]));
} else if (ret < 0) {
LOG_ERR("Error: cannot get property \"%s\": %d",
fuel_gauge_prop_to_str(test_props[i]), ret);
} else {
LOG_INF("Property \"%s\" is supported",
fuel_gauge_prop_to_str(test_props[i]));
switch (test_props[i]) {
case FUEL_GAUGE_AVG_CURRENT:
LOG_INF(" Avg current: %d",
test_vals[i].avg_current);
break;
case FUEL_GAUGE_CURRENT:
LOG_INF(" Current: %d", test_vals[i].current);
break;
case FUEL_GAUGE_CYCLE_COUNT:
LOG_INF(" Cycle count: %" PRIu32,
test_vals[i].cycle_count);
break;
case FUEL_GAUGE_CONNECT_STATE:
LOG_INF(" Connect state: 0x%" PRIx32,
test_vals[i].connect_state);
break;
case FUEL_GAUGE_FLAGS:
LOG_INF(" Flags: 0x%" PRIx32, test_vals[i].flags);
break;
case FUEL_GAUGE_FULL_CHARGE_CAPACITY:
LOG_INF(" Full charge capacity: %" PRIu32,
test_vals[i].full_charge_capacity);
break;
case FUEL_GAUGE_PRESENT_STATE:
LOG_INF(" Present state: %d",
test_vals[i].present_state);
break;
case FUEL_GAUGE_REMAINING_CAPACITY:
LOG_INF(" Remaining capacity: %" PRIu32,
test_vals[i].remaining_capacity);
break;
case FUEL_GAUGE_RUNTIME_TO_EMPTY:
LOG_INF(" Runtime to empty: %" PRIu32,
test_vals[i].runtime_to_empty);
break;
case FUEL_GAUGE_RUNTIME_TO_FULL:
LOG_INF(" Runtime to full: %" PRIu32,
test_vals[i].runtime_to_full);
break;
case FUEL_GAUGE_SBS_MFR_ACCESS:
LOG_INF(" SBS MFR access: %" PRIu16,
test_vals[i].sbs_mfr_access_word);
break;
case FUEL_GAUGE_ABSOLUTE_STATE_OF_CHARGE:
LOG_INF(" Absolute state of charge: %" PRIu8,
test_vals[i].absolute_state_of_charge);
break;
case FUEL_GAUGE_RELATIVE_STATE_OF_CHARGE:
LOG_INF(" Relative state of charge: %" PRIu8,
test_vals[i].relative_state_of_charge);
break;
case FUEL_GAUGE_TEMPERATURE:
LOG_INF(" Temperature: %" PRIu16,
test_vals[i].temperature);
break;
case FUEL_GAUGE_VOLTAGE:
LOG_INF(" Voltage: %d", test_vals[i].voltage);
break;
case FUEL_GAUGE_SBS_MODE:
LOG_INF(" SBS mode: %" PRIu16,
test_vals[i].sbs_mode);
break;
case FUEL_GAUGE_CHARGE_CURRENT:
LOG_INF(" Charge current: %" PRIu32,
test_vals[i].chg_current);
break;
case FUEL_GAUGE_CHARGE_VOLTAGE:
LOG_INF(" Charge voltage: %" PRIu32,
test_vals[i].chg_voltage);
break;
case FUEL_GAUGE_STATUS:
LOG_INF(" Status: 0x%" PRIx16,
test_vals[i].fg_status);
break;
case FUEL_GAUGE_DESIGN_CAPACITY:
LOG_INF(" Design capacity: %" PRIu16,
test_vals[i].design_cap);
break;
case FUEL_GAUGE_DESIGN_VOLTAGE:
LOG_INF(" Design voltage: %" PRIx16,
test_vals[i].design_volt);
break;
case FUEL_GAUGE_SBS_ATRATE:
LOG_INF(" SBS at rate: %" PRIi16,
test_vals[i].sbs_at_rate);
break;
case FUEL_GAUGE_SBS_ATRATE_TIME_TO_FULL:
LOG_INF(" SBS at rate time to full: %" PRIu16,
test_vals[i].sbs_at_rate_time_to_full);
break;
case FUEL_GAUGE_SBS_ATRATE_TIME_TO_EMPTY:
LOG_INF(" SBS at rate time to empty: %" PRIu16,
test_vals[i].sbs_at_rate_time_to_empty);
break;
case FUEL_GAUGE_SBS_ATRATE_OK:
LOG_INF(" SBS at rate ok: %d",
test_vals[i].sbs_at_rate_ok);
break;
case FUEL_GAUGE_SBS_REMAINING_CAPACITY_ALARM:
LOG_INF(" SBS remaining capacity alarm: %" PRIu16,
test_vals[i].sbs_remaining_capacity_alarm);
break;
case FUEL_GAUGE_SBS_REMAINING_TIME_ALARM:
LOG_INF(" SBS remaining time alarm: %" PRIu16,
test_vals[i].sbs_remaining_time_alarm);
break;
case FUEL_GAUGE_CURRENT_DIRECTION:
LOG_INF(" Current direction: %" PRIu16,
test_vals[i].current_direction);
break;
case FUEL_GAUGE_STATE_OF_CHARGE_ALARM:
LOG_INF(" State of charge alarm: %" PRIu8,
test_vals[i].state_of_charge_alarm);
break;
case FUEL_GAUGE_LOW_VOLTAGE_ALARM:
LOG_INF(" Low voltage alarm: %" PRIu32,
test_vals[i].low_voltage_alarm);
break;
}
}
}
}
}
LOG_INF("Polling fuel gauge data 'FUEL_GAUGE_RELATIVE_STATE_OF_CHARGE' & "
"'FUEL_GAUGE_VOLTAGE'");
while (1) {
fuel_gauge_prop_t poll_props[] = {
FUEL_GAUGE_RELATIVE_STATE_OF_CHARGE,
FUEL_GAUGE_VOLTAGE,
};
union fuel_gauge_prop_val poll_vals[ARRAY_SIZE(poll_props)];
ret = fuel_gauge_get_props(dev, poll_props, poll_vals, ARRAY_SIZE(poll_props));
if (ret < 0) {
LOG_ERR("Error: cannot get properties");
} else {
LOG_INF("Fuel gauge data: Charge: %d%%, Voltage: %dmV",
poll_vals[0].relative_state_of_charge, poll_vals[1].voltage / 1000);
}
k_sleep(K_MSEC(5000));
}
return 0;
}

5
samples/fuel_gauge/fuel_gauge.rst

@ -1,5 +0,0 @@ @@ -1,5 +0,0 @@
.. zephyr:code-sample-category:: fuel_gauge
:name: Fuel Gauge
:show-listing:
Samples that show how to interact with :ref:`fuel_gauge_api`.

51
samples/fuel_gauge/max17048/README.rst

@ -1,51 +0,0 @@ @@ -1,51 +0,0 @@
.. zephyr:code-sample:: max17048
:name: MAX17048 Li-Ion battery fuel gauge
Read battery percentage and power status using MAX17048 fuel gauge.
Overview
********
This sample shows how to use the Zephyr :ref:`fuel_gauge_api` API driver for the MAX17048 fuel gauge.
.. _MAX17048: https://www.maximintegrated.com/en/products/power/battery-management/MAX17048.html
The sample periodically reads battery percentage and power status
Building and Running
********************
The sample can be configured to support MAX17048 fuel gauge connected via either I2C. It only needs
an I2C pin configuration
Features
********
By using this fuel gauge you can get the following information:
* Battery charge status as percentage
* Total time until battery is fully charged or discharged
* Battery voltage
* Charging state: if charging or discharging
Notes
*****
The charging state and the time to full/empty are estimated and based on the last consumption average. That means that
if you plug/unplug a charger it will take some time until it is actually detected by the chip. Don't try to plug/unplug
to see in real time the charging status change because it will not work. If you really need to know exactly the moment
when the battery is being charged you will need other method.
Sample output
*************
```
*** Booting Zephyr OS build 16043f62a40a ***
Found device "max17048@36", getting fuel gauge data
Time to empty 1911
Time to full 0
Charge 72%
Voltage 3968
Time to empty 1911
Time to full 0
Charge 72%
Voltage 3968
```

8
samples/fuel_gauge/max17048/boards/adafruit_feather_esp32s2_C.overlay

@ -1,8 +0,0 @@ @@ -1,8 +0,0 @@
&i2c0 {
max17048: max17048@36 {
compatible = "maxim,max17048";
status = "okay";
reg = <0x36 >;
power-domains = <&i2c_reg>;
};
};

8
samples/fuel_gauge/max17048/boards/adafruit_feather_esp32s2_tft.overlay

@ -1,8 +0,0 @@ @@ -1,8 +0,0 @@
&i2c0 {
max17048: max17048@36 {
compatible = "maxim,max17048";
status = "okay";
reg = <0x36 >;
power-domains = <&i2c_reg>;
};
};

1
samples/fuel_gauge/max17048/prj.conf

@ -1 +0,0 @@ @@ -1 +0,0 @@
CONFIG_FUEL_GAUGE=y

9
samples/fuel_gauge/max17048/sample.yaml

@ -1,9 +0,0 @@ @@ -1,9 +0,0 @@
sample:
name: MAX17048 Sensor sample
tests:
sample.sensor.max17048:
build_only: true
platform_allow: nrf52dk/nrf52832
integration_platforms:
- nrf52dk/nrf52832
tags: fuel_gauge

67
samples/fuel_gauge/max17048/src/main.c

@ -1,67 +0,0 @@ @@ -1,67 +0,0 @@
/*
* Copyright (c) 2023 Alvaro Garcia Gomez <maxpowel@gmail.com>
*
* SPDX-License-Identifier: Apache-2.0
*/
#include "zephyr/sys/util.h"
#include <zephyr/kernel.h>
#include <zephyr/device.h>
#include <zephyr/devicetree.h>
#include <zephyr/drivers/fuel_gauge.h>
int main(void)
{
const struct device *const dev = DEVICE_DT_GET_ANY(maxim_max17048);
int ret = 0;
if (dev == NULL) {
printk("\nError: no device found.\n");
return 0;
}
if (!device_is_ready(dev)) {
printk("\nError: Device \"%s\" is not ready; "
"check the driver initialization logs for errors.\n",
dev->name);
return 0;
}
printk("Found device \"%s\", getting fuel gauge data\n", dev->name);
if (dev == NULL) {
return 0;
}
while (1) {
fuel_gauge_prop_t props[] = {
FUEL_GAUGE_RUNTIME_TO_EMPTY,
FUEL_GAUGE_RUNTIME_TO_FULL,
FUEL_GAUGE_RELATIVE_STATE_OF_CHARGE,
FUEL_GAUGE_VOLTAGE,
};
union fuel_gauge_prop_val vals[ARRAY_SIZE(props)];
ret = fuel_gauge_get_props(dev, props, vals, ARRAY_SIZE(props));
if (ret < 0) {
printk("Error: cannot get properties\n");
} else {
printk("Time to empty %d minutes\n", vals[0].runtime_to_empty);
printk("Time to full %d minutes\n", vals[1].runtime_to_full);
printk("Charge %d%%\n", vals[2].relative_state_of_charge);
printk("Voltage %d\n uV", vals[3].voltage);
}
k_sleep(K_MSEC(5000));
}
return 0;
}
Loading…
Cancel
Save