Browse Source
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
24 changed files with 574 additions and 150 deletions
@ -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,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,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,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,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,0 +1,4 @@
@@ -0,0 +1,4 @@
|
||||
CONFIG_FUEL_GAUGE=y |
||||
CONFIG_I2C=y |
||||
CONFIG_LOG=y |
||||
CONFIG_LOG_BUFFER_SIZE=4096 |
@ -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 |
@ -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; |
||||
} |
@ -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`. |
@ -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 |
||||
``` |
@ -1,8 +0,0 @@
@@ -1,8 +0,0 @@
|
||||
&i2c0 { |
||||
max17048: max17048@36 { |
||||
compatible = "maxim,max17048"; |
||||
status = "okay"; |
||||
reg = <0x36 >; |
||||
power-domains = <&i2c_reg>; |
||||
}; |
||||
}; |
@ -1,8 +0,0 @@
@@ -1,8 +0,0 @@
|
||||
&i2c0 { |
||||
max17048: max17048@36 { |
||||
compatible = "maxim,max17048"; |
||||
status = "okay"; |
||||
reg = <0x36 >; |
||||
power-domains = <&i2c_reg>; |
||||
}; |
||||
}; |
@ -1 +0,0 @@
@@ -1 +0,0 @@
|
||||
CONFIG_FUEL_GAUGE=y |
@ -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 |
@ -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…
Reference in new issue