1 /*
2 * Copyright 2024 Embeint Inc
3 *
4 * SPDX-License-Identifier: Apache-2.0
5 */
6
7 #ifndef ZEPHYR_INCLUDE_DRIVERS_SENSOR_BATTERY_H_
8 #define ZEPHYR_INCLUDE_DRIVERS_SENSOR_BATTERY_H_
9
10 #include <stdint.h>
11 #include <errno.h>
12
13 #include <zephyr/devicetree.h>
14 #include <zephyr/math/interpolation.h>
15 #include <zephyr/sys/util_macro.h>
16
17 #ifdef __cplusplus
18 extern "C" {
19 #endif
20
21 /**
22 * @brief battery API
23 * @defgroup battery_apis battery APIs
24 * @{
25 */
26
27 /* Battery chemistry enumeration.
28 * Value names must match those from dts/bindings/battery.yaml
29 */
30 enum battery_chemistry {
31 BATTERY_CHEMISTRY_UNKNOWN = 0,
32 BATTERY_CHEMISTRY_NICKEL_CADMIUM,
33 BATTERY_CHEMISTRY_NICKEL_METAL_HYDRIDE,
34 BATTERY_CHEMISTRY_LITHIUM_ION,
35 BATTERY_CHEMISTRY_LITHIUM_ION_POLYMER,
36 BATTERY_CHEMISTRY_LITHIUM_ION_IRON_PHOSPHATE,
37 BATTERY_CHEMISTRY_LITHIUM_ION_MANGANESE_OXIDE,
38 };
39
40 /* Length of open circuit voltage table */
41 #define BATTERY_OCV_TABLE_LEN 11
42
43 /**
44 * @brief Get the battery chemistry enum value
45 *
46 * @param node_id node identifier
47 */
48 #define BATTERY_CHEMISTRY_DT_GET(node_id) \
49 UTIL_CAT(BATTERY_CHEMISTRY_, DT_STRING_UPPER_TOKEN_OR(node_id, device_chemistry, UNKNOWN))
50
51 /**
52 * @brief Get the OCV curve for a given table
53 *
54 * @param node_id node identifier
55 * @param table table to retrieve
56 */
57 #define BATTERY_OCV_TABLE_DT_GET(node_id, table) \
58 COND_CODE_1(DT_NODE_HAS_PROP(node_id, table), \
59 ({DT_FOREACH_PROP_ELEM_SEP(node_id, table, DT_PROP_BY_IDX, (,))}), ({-1}))
60
61 /**
62 * @brief Convert an OCV table and battery voltage to a charge percentage
63 *
64 * @param ocv_table Open circuit voltage curve
65 * @param voltage_uv Battery voltage in microVolts
66 *
67 * @returns Battery state of charge in milliPercent
68 */
battery_soc_lookup(const int32_t ocv_table[BATTERY_OCV_TABLE_LEN],uint32_t voltage_uv)69 static inline int32_t battery_soc_lookup(const int32_t ocv_table[BATTERY_OCV_TABLE_LEN],
70 uint32_t voltage_uv)
71 {
72 static const int32_t soc_axis[BATTERY_OCV_TABLE_LEN] = {
73 0, 10000, 20000, 30000, 40000, 50000, 60000, 70000, 80000, 90000, 100000};
74
75 /* Convert voltage to SoC */
76 return linear_interpolate(ocv_table, soc_axis, BATTERY_OCV_TABLE_LEN, voltage_uv);
77 }
78
79 /**
80 * @}
81 */
82
83 #ifdef __cplusplus
84 }
85 #endif
86
87 #endif /* ZEPHYR_INCLUDE_DRIVERS_SENSOR_BATTERY_H_ */
88