1 /*
2  * Copyright (c) 2025 Philipp Steiner <philipp.steiner1987@gmail.com>
3  *
4  * SPDX-License-Identifier: Apache-2.0
5  */
6 
7 #include <zephyr/device.h>
8 #include <zephyr/drivers/fuel_gauge.h>
9 #include <zephyr/drivers/i2c.h>
10 #include <zephyr/logging/log.h>
11 #include <zephyr/sys/byteorder.h>
12 #include <zephyr/sys/util.h>
13 #include <zephyr/ztest.h>
14 #include <zephyr/ztest_assert.h>
15 
16 struct lc709203f_fixture {
17 	const struct device *dev;
18 	const struct fuel_gauge_driver_api *api;
19 };
20 
lc709203f_setup(void)21 static void *lc709203f_setup(void)
22 {
23 	static ZTEST_DMEM struct lc709203f_fixture fixture;
24 
25 	fixture.dev = DEVICE_DT_GET_ANY(onnn_lc709203f);
26 	k_object_access_all_grant(fixture.dev);
27 
28 	zassert_true(device_is_ready(fixture.dev), "Fuel Gauge not found");
29 
30 	return &fixture;
31 }
32 
ZTEST_USER_F(lc709203f,test_get_some_props_failed__returns_bad_status)33 ZTEST_USER_F(lc709203f, test_get_some_props_failed__returns_bad_status)
34 {
35 	fuel_gauge_prop_t props[] = {
36 		/* First invalid property */
37 		FUEL_GAUGE_PROP_MAX,
38 		/* Second invalid property */
39 		FUEL_GAUGE_PROP_MAX,
40 		/* Valid property */
41 		FUEL_GAUGE_VOLTAGE,
42 	};
43 	union fuel_gauge_prop_val vals[ARRAY_SIZE(props)];
44 
45 	int ret = fuel_gauge_get_props(fixture->dev, props, vals, ARRAY_SIZE(props));
46 
47 	zassert_equal(ret, -ENOTSUP, "Getting bad property has a good status.");
48 }
49 
ZTEST_USER_F(lc709203f,test_set_all_props_failed__returns_err)50 ZTEST_USER_F(lc709203f, test_set_all_props_failed__returns_err)
51 {
52 	fuel_gauge_prop_t prop_types[] = {
53 		/* Invalid property */
54 		FUEL_GAUGE_PROP_MAX,
55 	};
56 	union fuel_gauge_prop_val props[ARRAY_SIZE(prop_types)] = {0};
57 
58 	int ret = fuel_gauge_set_props(fixture->dev, prop_types, props, ARRAY_SIZE(props));
59 
60 	zassert_equal(ret, -ENOTSUP);
61 }
62 
ZTEST_USER_F(lc709203f,test_set_some_props_failed__returns_err)63 ZTEST_USER_F(lc709203f, test_set_some_props_failed__returns_err)
64 {
65 	fuel_gauge_prop_t prop_types[] = {
66 		/* First invalid property */
67 		FUEL_GAUGE_PROP_MAX,
68 		/* Second invalid property */
69 		FUEL_GAUGE_PROP_MAX,
70 		/* Valid property */
71 		FUEL_GAUGE_STATE_OF_CHARGE_ALARM,
72 		/* Set Manufacturer's Access to arbitrary word */
73 
74 	};
75 
76 	union fuel_gauge_prop_val props[] = {
77 		/* First invalid property */
78 		{0},
79 		/* Second invalid property */
80 		{0},
81 		/* Valid property */
82 		/* Sets state of charge threshold to generate Alarm signal*/
83 		{.state_of_charge_alarm = 10},
84 	};
85 
86 	int ret = fuel_gauge_set_props(fixture->dev, prop_types, props, ARRAY_SIZE(props));
87 
88 	zassert_equal(ret, -ENOTSUP);
89 }
90 
ZTEST_USER_F(lc709203f,test_set_prop_can_be_get)91 ZTEST_USER_F(lc709203f, test_set_prop_can_be_get)
92 {
93 	uint16_t sbs_mode = 0x0002;
94 	uint16_t current_direction = 0x0001;
95 	uint8_t state_of_charge_alarm = 20;
96 	uint32_t low_voltage_alarm = 3000 * 1000;
97 
98 	fuel_gauge_prop_t prop_types[] = {
99 		FUEL_GAUGE_SBS_MODE,
100 		FUEL_GAUGE_CURRENT_DIRECTION,
101 		FUEL_GAUGE_STATE_OF_CHARGE_ALARM,
102 		FUEL_GAUGE_LOW_VOLTAGE_ALARM,
103 	};
104 
105 	union fuel_gauge_prop_val set_props[] = {
106 		{
107 			.sbs_mode = sbs_mode,
108 		},
109 		{
110 			.current_direction = current_direction,
111 		},
112 		{
113 			.state_of_charge_alarm = state_of_charge_alarm,
114 		},
115 		{
116 			.low_voltage_alarm = low_voltage_alarm,
117 		},
118 	};
119 
120 	union fuel_gauge_prop_val get_props[ARRAY_SIZE(prop_types)];
121 
122 	zassert_ok(
123 		fuel_gauge_set_props(fixture->dev, prop_types, set_props, ARRAY_SIZE(set_props)));
124 
125 	zassert_ok(
126 		fuel_gauge_get_props(fixture->dev, prop_types, get_props, ARRAY_SIZE(get_props)));
127 
128 	zassert_equal(get_props[0].sbs_mode, sbs_mode);
129 	zassert_equal(get_props[1].current_direction, current_direction);
130 	zassert_equal(get_props[2].state_of_charge_alarm, state_of_charge_alarm);
131 	zassert_equal(get_props[3].low_voltage_alarm, low_voltage_alarm);
132 }
133 
ZTEST_USER_F(lc709203f,test_get_props__returns_ok)134 ZTEST_USER_F(lc709203f, test_get_props__returns_ok)
135 {
136 	fuel_gauge_prop_t props[] = {
137 		FUEL_GAUGE_RELATIVE_STATE_OF_CHARGE,
138 		FUEL_GAUGE_TEMPERATURE,
139 		FUEL_GAUGE_VOLTAGE,
140 		FUEL_GAUGE_SBS_MODE,
141 		FUEL_GAUGE_DESIGN_CAPACITY,
142 		FUEL_GAUGE_CURRENT_DIRECTION,
143 		FUEL_GAUGE_STATE_OF_CHARGE_ALARM,
144 		FUEL_GAUGE_LOW_VOLTAGE_ALARM,
145 	};
146 	union fuel_gauge_prop_val vals[ARRAY_SIZE(props)];
147 
148 	int ret = fuel_gauge_get_props(fixture->dev, props, vals, ARRAY_SIZE(props));
149 
150 #if CONFIG_EMUL
151 	zassert_equal(vals[0].relative_state_of_charge, 50);
152 	zassert_equal(vals[1].temperature, 0x0BA6);
153 	zassert_equal(vals[2].voltage, 3700 * 1000);
154 	zassert_equal(vals[3].sbs_mode, 0x0001);
155 	zassert_equal(vals[4].design_cap, 500);
156 	zassert_true(((vals[5].current_direction == 0x0000) ||
157 		      (vals[5].current_direction == 0x0001) ||
158 		      (vals[5].current_direction == 0xFFFF)));
159 	zassert_equal(vals[6].state_of_charge_alarm, 0x0008);
160 	zassert_equal(vals[7].low_voltage_alarm, 0x0000);
161 #else
162 	zassert_between_inclusive(vals[0].relative_state_of_charge, 0, 100);
163 	zassert_between_inclusive(vals[1].temperature, 0x09E4, 0x0D04);
164 	zassert_between_inclusive(vals[2].voltage, 0, 0xFFFF * 1000);
165 	zassert_between_inclusive(vals[3].sbs_mode, 0x0001, 0x0002);
166 	zassert_true(((vals[4].design_cap == 100) || (vals[4].design_cap == 200) ||
167 		      (vals[4].design_cap == 500) || (vals[4].design_cap == 1000) ||
168 		      (vals[4].design_cap == 3000)));
169 	zassert_true(((vals[5].current_direction == 0x0000) ||
170 		      (vals[5].current_direction == 0x0001) ||
171 		      (vals[5].current_direction == 0xFFFF)));
172 	zassert_between_inclusive(vals[6].state_of_charge_alarm, 0, 100);
173 	zassert_between_inclusive(vals[7].low_voltage_alarm, 0, 0xFFFF * 1000);
174 #endif
175 
176 	zassert_equal(ret, 0, "Getting bad property has a good status.");
177 }
178 
ZTEST_USER_F(lc709203f,test_set_get_single_prop)179 ZTEST_USER_F(lc709203f, test_set_get_single_prop)
180 {
181 	uint8_t test_value = 5;
182 
183 	union fuel_gauge_prop_val state_of_charge_alarm_set = {
184 		.state_of_charge_alarm = test_value,
185 	};
186 	union fuel_gauge_prop_val state_of_charge_alarm_get;
187 
188 	zassert_ok(fuel_gauge_set_prop(fixture->dev, FUEL_GAUGE_STATE_OF_CHARGE_ALARM,
189 				       state_of_charge_alarm_set));
190 	zassert_ok(fuel_gauge_get_prop(fixture->dev, FUEL_GAUGE_STATE_OF_CHARGE_ALARM,
191 				       &state_of_charge_alarm_get));
192 	zassert_equal(state_of_charge_alarm_get.state_of_charge_alarm, test_value);
193 }
194 
195 ZTEST_SUITE(lc709203f, NULL, lc709203f_setup, NULL, NULL, NULL);
196