1 /*
2  * Copyright (c) 2023, ithinx GmbH
3  * Copyright (c) 2023, Tonies GmbH
4  *
5  * SPDX-License-Identifier: Apache-2.0
6  */
7 
8 #include <zephyr/device.h>
9 #include <zephyr/drivers/fuel_gauge.h>
10 #include <zephyr/drivers/i2c.h>
11 #include <zephyr/logging/log.h>
12 #include <zephyr/sys/byteorder.h>
13 #include <zephyr/sys/util.h>
14 #include <zephyr/ztest.h>
15 #include <zephyr/ztest_assert.h>
16 
17 struct bq27z746_fixture {
18 	const struct device *dev;
19 	const struct fuel_gauge_driver_api *api;
20 };
21 
bq27z746_setup(void)22 static void *bq27z746_setup(void)
23 {
24 	static ZTEST_DMEM struct bq27z746_fixture fixture;
25 
26 	fixture.dev = DEVICE_DT_GET_ANY(ti_bq27z746);
27 	k_object_access_all_grant(fixture.dev);
28 
29 	zassert_true(device_is_ready(fixture.dev), "Fuel Gauge not found");
30 
31 	return &fixture;
32 }
33 
ZTEST_USER_F(bq27z746,test_get_some_props_failed_returns_bad_status)34 ZTEST_USER_F(bq27z746, test_get_some_props_failed_returns_bad_status)
35 {
36 	fuel_gauge_prop_t props[] = {
37 		/* First invalid property */
38 		FUEL_GAUGE_PROP_MAX,
39 		/* Second invalid property */
40 		FUEL_GAUGE_PROP_MAX,
41 		/* Valid property */
42 		FUEL_GAUGE_VOLTAGE,
43 	};
44 	union fuel_gauge_prop_val vals[ARRAY_SIZE(props)];
45 
46 	int ret = fuel_gauge_get_props(fixture->dev, props, vals, ARRAY_SIZE(props));
47 
48 	zassert_equal(ret, -ENOTSUP, "Getting bad property has a good status.");
49 }
50 
ZTEST_USER_F(bq27z746,test_get_buffer_prop)51 ZTEST_USER_F(bq27z746, test_get_buffer_prop)
52 {
53 	int ret;
54 
55 	{
56 		struct sbs_gauge_manufacturer_name mfg_name;
57 
58 		ret = fuel_gauge_get_buffer_prop(fixture->dev, FUEL_GAUGE_MANUFACTURER_NAME,
59 						 &mfg_name, sizeof(mfg_name));
60 		zassert_ok(ret);
61 #if CONFIG_EMUL
62 		/* Only test for fixed values in emulation since the real device might be */
63 		/* reprogrammed and respond with different values */
64 		zassert_equal(sizeof("Texas Instruments") - 1, mfg_name.manufacturer_name_length);
65 		zassert_mem_equal(mfg_name.manufacturer_name, "Texas Instruments",
66 				  mfg_name.manufacturer_name_length,
67 				  "mfg_name.manufacturer_name='%s'", mfg_name.manufacturer_name);
68 #endif
69 	}
70 	{
71 		struct sbs_gauge_device_name dev_name;
72 
73 		ret = fuel_gauge_get_buffer_prop(fixture->dev, FUEL_GAUGE_DEVICE_NAME, &dev_name,
74 						 sizeof(dev_name));
75 		zassert_ok(ret);
76 #if CONFIG_EMUL
77 		/* Only test for fixed values in emulation since the real device might be */
78 		/* reprogrammed and respond with different values */
79 		zassert_equal(sizeof("BQ27Z746") - 1, dev_name.device_name_length);
80 		zassert_mem_equal(dev_name.device_name, "BQ27Z746", dev_name.device_name_length);
81 #endif
82 	}
83 	{
84 		struct sbs_gauge_device_chemistry device_chemistry;
85 
86 		ret = fuel_gauge_get_buffer_prop(fixture->dev, FUEL_GAUGE_DEVICE_CHEMISTRY,
87 						 &device_chemistry, sizeof(device_chemistry));
88 		zassert_ok(ret);
89 #if CONFIG_EMUL
90 		/* Only test for fixed values in emulation since the real device might be */
91 		/* reprogrammed and respond with different values */
92 		zassert_equal(sizeof("LION") - 1, device_chemistry.device_chemistry_length);
93 		zassert_mem_equal(device_chemistry.device_chemistry, "LION",
94 				  device_chemistry.device_chemistry_length);
95 #endif
96 	}
97 }
98 
ZTEST_USER_F(bq27z746,test_get_props__returns_ok)99 ZTEST_USER_F(bq27z746, test_get_props__returns_ok)
100 {
101 	/* Validate what props are supported by the driver */
102 
103 	fuel_gauge_prop_t props[] = {
104 			FUEL_GAUGE_AVG_CURRENT,
105 			FUEL_GAUGE_CYCLE_COUNT,
106 			FUEL_GAUGE_CURRENT,
107 			FUEL_GAUGE_FULL_CHARGE_CAPACITY,
108 			FUEL_GAUGE_REMAINING_CAPACITY,
109 			FUEL_GAUGE_RUNTIME_TO_EMPTY,
110 			FUEL_GAUGE_RUNTIME_TO_FULL,
111 			FUEL_GAUGE_SBS_MFR_ACCESS,
112 			FUEL_GAUGE_RELATIVE_STATE_OF_CHARGE,
113 			FUEL_GAUGE_TEMPERATURE,
114 			FUEL_GAUGE_VOLTAGE,
115 			FUEL_GAUGE_SBS_ATRATE,
116 			FUEL_GAUGE_SBS_ATRATE_TIME_TO_EMPTY,
117 			FUEL_GAUGE_CHARGE_VOLTAGE,
118 			FUEL_GAUGE_CHARGE_CURRENT,
119 			FUEL_GAUGE_STATUS,
120 			FUEL_GAUGE_DESIGN_CAPACITY,
121 	};
122 	union fuel_gauge_prop_val vals[ARRAY_SIZE(props)];
123 
124 	zassert_ok(fuel_gauge_get_props(fixture->dev, props, vals, ARRAY_SIZE(props)));
125 
126 	/* Check properties for valid ranges */
127 #if CONFIG_EMUL
128 	/* When emulating, check for the fixed values coming from the emulator */
129 	zassert_equal(vals[0].avg_current, -2000);
130 	zassert_equal(vals[1].cycle_count, 100);
131 	zassert_equal(vals[2].current, -2000);
132 	zassert_equal(vals[3].full_charge_capacity, 1000);
133 	zassert_equal(vals[4].remaining_capacity, 1000);
134 	zassert_equal(vals[5].runtime_to_empty, 1);
135 	zassert_equal(vals[6].runtime_to_full, 1);
136 	zassert_equal(vals[7].sbs_mfr_access_word, 1);
137 	zassert_equal(vals[8].relative_state_of_charge, 1);
138 	zassert_equal(vals[9].temperature, 1);
139 	zassert_equal(vals[10].voltage, 1000);
140 	zassert_equal(vals[11].sbs_at_rate, -2);
141 	zassert_equal(vals[12].sbs_at_rate_time_to_empty, 1);
142 	zassert_equal(vals[13].chg_voltage, 1000);
143 	zassert_equal(vals[14].chg_current, 1000);
144 	zassert_equal(vals[15].fg_status, 1);
145 	zassert_equal(vals[16].design_cap, 1);
146 #else
147 	/* When having a real device, check for the valid ranges */
148 	zassert_between_inclusive(props[0].avg_current, -32768 * 1000, 32767 * 1000);
149 	zassert_between_inclusive(props[1].cycle_count, 0, 6553500);
150 	zassert_between_inclusive(props[2].current, -32768 * 1000, 32767 * 1000);
151 	zassert_between_inclusive(props[3].full_charge_capacity, 0, 32767 * 1000);
152 	zassert_between_inclusive(props[4].remaining_capacity, 0, 32767 * 1000);
153 	zassert_between_inclusive(props[5].runtime_to_empty, 0, 65535);
154 	zassert_between_inclusive(props[6].runtime_to_full, 0, 65535);
155 	/* Not testing props[7]. This is the manufacturer access and has only status bits */
156 	zassert_between_inclusive(props[8].relative_state_of_charge, 0, 100);
157 	zassert_between_inclusive(props[9].temperature, 0, 32767);
158 	zassert_between_inclusive(props[10].voltage, 0, 32767 * 1000);
159 	zassert_between_inclusive(props[11].sbs_at_rate, -32768, 32767);
160 	zassert_between_inclusive(props[12].sbs_at_rate_time_to_empty, 0, 65535);
161 	zassert_between_inclusive(props[13].chg_voltage, 0, 32767);
162 	zassert_between_inclusive(props[14].chg_current, 0, 32767);
163 	/* Not testing props[15]. This property is the status and only has only status bits */
164 	zassert_between_inclusive(props[16].design_cap, 0, 32767);
165 #endif
166 }
167 
168 ZTEST_SUITE(bq27z746, NULL, bq27z746_setup, NULL, NULL, NULL);
169