1 /*
2  * Copyright (c) 2022 Thomas Stranger
3  *
4  * SPDX-License-Identifier: Apache-2.0
5  */
6 
7 #include <zephyr/drivers/sensor.h>
8 #include <zephyr/drivers/sensor/w1_sensor.h>
9 #include <zephyr/drivers/w1.h>
10 #include <zephyr/kernel.h>
11 #include <zephyr/ztest.h>
12 
13 #define W1_MASTER  DT_NODELABEL(w1_0)
14 #define W1_SLAVE_1 DT_NODELABEL(slave_1)
15 #define W1_SLAVE_2 DT_NODELABEL(slave_2)
16 
get_w1_master_dev(void)17 const struct device *get_w1_master_dev(void)
18 {
19 	const struct device *const master_dev = DEVICE_DT_GET(W1_MASTER);
20 
21 	zassert_true(device_is_ready(master_dev), "W1 master not found");
22 
23 	return master_dev;
24 }
25 
26 /* test vectors: */
27 const uint8_t rom_01_bytes[] = { 0x2d, 0x18, 0x08, 0xf5, 0x2d, 0x00, 0x00, 0x67 };
28 const uint8_t rom_02_bytes[] = { 0x2d, 0x2d, 0xfc, 0xf4, 0x2d, 0x00, 0x00, 0x57 };
29 const uint8_t rom_03_bytes[] = { 0x48, 0xa8, 0xdc, 0xf2, 0xb7, 0x01, 0x30, 0x7e };
30 
31 const uint64_t rom_01_64 = 0x2d1808f52d000067;
32 const uint64_t rom_02_64 = 0x2d2dfcf42d000057;
33 const uint64_t rom_03_64 = 0xa8a8dcf2b701307e;
34 
35 const struct w1_rom rom_01 = {
36 	.family = 0x2d,
37 	.serial = { 0x18, 0x08, 0xf5, 0x2d, 0x00, 0x00 },
38 	.crc = 0x67,
39 };
40 const struct w1_rom rom_02 = {
41 	.family = 0x2d,
42 	.serial = { 0x2d, 0xfc, 0xf4, 0x2d, 0x00, 0x00 },
43 	.crc = 0x57,
44 };
45 const struct w1_rom rom_03 = {
46 	.family = 0xa8,
47 	.serial = { 0xa8, 0xdc, 0xf2, 0xb7, 0x01, 0x30 },
48 	.crc = 0x7e,
49 };
50 
51 const uint8_t crc16_1_in[11] = { 0x0f, 0x00, 0x00, 0xff, 0xee, 0xdd,
52 				 0xcc, 0xdd, 0xcc, 0xbb, 0xff };
53 const uint16_t crc16_1 = 0x60bb;
54 const uint8_t crc16_2_in[11] = { 0x0f, 0x08, 0x00, 0xaa, 0xbb, 0xcc,
55 				 0xdd, 0xaa, 0xbb, 0xcc, 0xdd };
56 const uint16_t crc16_2 = 0x8909;
57 const uint8_t crc16_3_in[12] = { 0xaa, 0x00, 0x00, 0x07, 0x00, 0x00,
58 				 0x00, 0xcc, 0xaa, 0xbb, 0xcc, 0xdd };
59 const uint16_t crc16_3 = 0x5d69;
60 
ZTEST_USER(w1_api,test_w1_basic)61 ZTEST_USER(w1_api, test_w1_basic)
62 {
63 	const struct device *master_dev = get_w1_master_dev();
64 	size_t slave_count;
65 	int slave1_family = DT_PROP(W1_SLAVE_1, family_code);
66 	bool slave1_overdrive = DT_PROP(W1_SLAVE_1, overdrive_speed);
67 
68 	zassert_equal(slave1_family, 0x28, "slave 1 family code not matching");
69 	zassert_true(slave1_overdrive, "slave 1 overdrive param. not matching");
70 
71 	zassert_equal(w1_lock_bus(master_dev), 0, "Fail lock 1");
72 	zassert_equal(w1_lock_bus(master_dev), 0, "Fail lock 2");
73 	zassert_equal(w1_unlock_bus(master_dev), 0, "Fail unlock 1");
74 	zassert_equal(w1_unlock_bus(master_dev), 0, "Fail unlock 2");
75 
76 	slave_count = w1_get_slave_count(master_dev);
77 	zassert_equal(slave_count, 2,
78 		      "slave_count does not match dt definitions: %u/2",
79 		      slave_count);
80 }
81 
ZTEST_USER(w1_api,test_w1_crc)82 ZTEST_USER(w1_api, test_w1_crc)
83 {
84 	uint8_t crc8_result;
85 	uint16_t crc16_result;
86 
87 	/* crc8 */
88 	crc8_result = w1_crc8(rom_01_bytes, 8);
89 	zassert_equal(crc8_result, 0, "crc1: crc over complete rom not 0");
90 
91 	crc8_result = w1_crc8(rom_02_bytes, 8);
92 	zassert_equal(crc8_result, 0, "crc2: crc over complete rom not 0");
93 
94 	crc8_result = w1_crc8(rom_03_bytes, 7);
95 	zassert_equal(crc8_result, rom_03_bytes[7], "crc3 does not match");
96 
97 	/* crc16 */
98 	crc16_result = w1_crc16(W1_CRC16_SEED, crc16_1_in, sizeof(crc16_1_in));
99 	zassert_equal(crc16_result, crc16_1, "crc16_1 does not match");
100 
101 	crc16_result = w1_crc16(W1_CRC16_SEED, crc16_2_in, sizeof(crc16_2_in));
102 	zassert_equal(crc16_result, crc16_2, "crc16_2 does not match");
103 
104 	crc16_result = w1_crc16(W1_CRC16_SEED, crc16_3_in, sizeof(crc16_3_in));
105 	zassert_equal(crc16_result, crc16_3, "crc16_3 does not match");
106 }
107 
ZTEST_USER(w1_api,test_w1_rom)108 ZTEST_USER(w1_api, test_w1_rom)
109 {
110 	struct w1_rom rom_x;
111 	uint64_t rom_x_64 = -1;
112 
113 	rom_x_64 = w1_rom_to_uint64(&rom_01);
114 	zassert_equal(rom_01_64, rom_x_64,
115 		      "rom_01_struct converted to uint64 does not match");
116 	rom_x_64 = w1_rom_to_uint64(&rom_02);
117 	zassert_equal(rom_02_64, rom_x_64,
118 		      "rom_02_struct converted to uint64 does not match");
119 	rom_x_64 = w1_rom_to_uint64(&rom_03);
120 	zassert_equal(rom_03_64, rom_x_64,
121 		      "rom_03_struct converted to uint64 does not match");
122 
123 	w1_uint64_to_rom(rom_01_64, &rom_x);
124 	zassert_mem_equal(&rom_x, &rom_01, sizeof(rom_01),
125 			  "rom_01_64 converted to rom struct does not match");
126 	w1_uint64_to_rom(rom_02_64, &rom_x);
127 	zassert_mem_equal(&rom_x, &rom_02, sizeof(rom_02),
128 			  "rom_02_64 converted to rom struct does not match");
129 	w1_uint64_to_rom(rom_03_64, &rom_x);
130 	zassert_mem_equal(&rom_x, &rom_03, sizeof(rom_03),
131 			  "rom_03_64 converted to rom struct does not match");
132 }
133 
ZTEST_USER(w1_api,test_w1_rom_sensor_value)134 ZTEST_USER(w1_api, test_w1_rom_sensor_value)
135 {
136 	struct w1_rom rom_x;
137 	struct sensor_value sensor_val = {-1, -1};
138 
139 	w1_rom_to_sensor_value(&rom_01, &sensor_val);
140 	w1_sensor_value_to_rom(&sensor_val, &rom_x);
141 	zassert_mem_equal(&rom_x, &rom_01, sizeof(rom_01),
142 			  "rom_01 sensor-value conversion failed: %llx", rom_01_64);
143 
144 	w1_rom_to_sensor_value(&rom_02, &sensor_val);
145 	w1_sensor_value_to_rom(&sensor_val, &rom_x);
146 	zassert_mem_equal(&rom_x, &rom_02, sizeof(rom_02),
147 			  "rom_02 sensor-value conversion failed: %llx", rom_02_64);
148 
149 	w1_rom_to_sensor_value(&rom_03, &sensor_val);
150 	w1_sensor_value_to_rom(&sensor_val, &rom_x);
151 	zassert_mem_equal(&rom_x, &rom_03, sizeof(rom_03),
152 			  "rom_03 sensor-value conversion failed: %llx", rom_03_64);
153 }
154 
ZTEST_USER(w1_api,test_w1_reset_empty)155 ZTEST_USER(w1_api, test_w1_reset_empty)
156 {
157 	int ret;
158 	const struct device *master_dev = get_w1_master_dev();
159 
160 	ret = w1_reset_bus(master_dev);
161 	zassert_false((ret < 0), "w1_reset failed. Err: %d", ret);
162 	zassert_equal(ret, 0, "In case no devices are connected should return 0");
163 }
164 
165 int found_w1_devices;
166 
w1_test_search_callback(struct w1_rom found_rom,void * callback_arg)167 void w1_test_search_callback(struct w1_rom found_rom, void *callback_arg)
168 {
169 	ARG_UNUSED(callback_arg);
170 	TC_PRINT("rom: %016llx\n", w1_rom_to_uint64(&found_rom));
171 	found_w1_devices++;
172 }
173 
ZTEST(w1_api,test_w1_search_empty)174 ZTEST(w1_api, test_w1_search_empty)
175 {
176 	int ret;
177 	const struct device *master_dev = get_w1_master_dev();
178 
179 	ret = w1_search_rom(master_dev, w1_test_search_callback, 0);
180 	zassert_equal(ret, 0, "In case no slaves are connected should return 0");
181 	zassert_equal(found_w1_devices, 0, "No callback exptected");
182 
183 	ret = w1_search_rom(master_dev, 0, 0);
184 	zassert_equal(ret, 0, "In case no slaves are connected should return 0");
185 
186 	ret = w1_search_alarm(master_dev, 0, 0);
187 	zassert_equal(ret, 0, "In case no devices are connected should return 0");
188 	zassert_equal(found_w1_devices, 0, "No callback exptected");
189 }
190 
ZTEST_USER(w1_api,test_w1_fire_and_forget)191 ZTEST_USER(w1_api, test_w1_fire_and_forget)
192 {
193 	int ret;
194 	const struct device *master_dev = get_w1_master_dev();
195 	const uint8_t block_send[8] = { 0x0F, 0x0E, 0x0D, 0x0C, 0xC0, 0xD0, 0xE0, 0xF0 };
196 
197 	ret = w1_write_bit(master_dev, false);
198 	zassert_equal(ret, 0, "write_bit: error: %d", ret);
199 
200 	ret = w1_write_byte(master_dev, 0x3b);
201 	zassert_equal(ret, 0, "write_byte: error: %d", ret);
202 
203 	ret = w1_write_block(master_dev, block_send, sizeof(block_send));
204 	zassert_equal(ret, 0, "write_block: error: %d", ret);
205 }
206 
ZTEST_USER(w1_api,test_w1_receive_nothing)207 ZTEST_USER(w1_api, test_w1_receive_nothing)
208 {
209 	int ret;
210 	const struct device *master_dev = get_w1_master_dev();
211 	uint8_t block_rcv[8] = { 0x0F, 0x0E, 0x0D, 0x0C, 0xC0, 0xD0, 0xE0, 0xF0 };
212 	const uint8_t block_ref[8] = { 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF };
213 
214 	/* on idle bus without sender all received bits should be logical ones */
215 
216 	ret = w1_read_bit(master_dev);
217 	zassert_true((ret >= 0), "read_bit: error: %d", ret);
218 	zassert_equal(ret, 1, "bit: empty receive should be logical ones");
219 
220 	ret = w1_read_byte(master_dev);
221 	zassert_true((ret >= 0), "read_byte: error: %d", ret);
222 	zassert_equal(ret, 0xFF, "byte: empty receive should be logical 0xFF");
223 
224 	ret = w1_read_block(master_dev, block_rcv, sizeof(block_rcv));
225 	zassert_equal(ret, 0, "read_block: error: %d", ret);
226 	zassert_mem_equal(block_rcv, block_ref, sizeof(block_rcv),
227 			  "block: empty receive should be local all 0xFF");
228 }
229 
ZTEST_USER(w1_api,test_w1_slave)230 ZTEST_USER(w1_api, test_w1_slave)
231 {
232 	int ret;
233 	struct w1_slave_config cfg_1 = { .rom = {} };
234 	const struct device *master_dev = get_w1_master_dev();
235 	const uint8_t block_send[8] = { 0x0F, 0x0E, 0x0D, 0x0C, 0xC0, 0xD0, 0xE0, 0xF0 };
236 	uint8_t block_rcv[8] = { 0x00 };
237 
238 	ret = w1_read_rom(master_dev, &cfg_1.rom);
239 	zassert_equal(ret, -ENODEV, "read_rom should fail w/o connected dev");
240 
241 	ret = w1_match_rom(master_dev, &cfg_1);
242 	zassert_equal(ret, -ENODEV, "match_rom should fail w/o connected dev");
243 
244 	ret = w1_resume_command(master_dev);
245 	zassert_equal(ret, -ENODEV, "resume command should fail w/o connected dev");
246 
247 	ret = w1_skip_rom(master_dev, &cfg_1);
248 	zassert_equal(ret, -ENODEV, "skip_rom should fail w/o connected dev");
249 
250 	ret = w1_reset_select(master_dev, &cfg_1);
251 	zassert_equal(ret, -ENODEV, "reset_select should fail w/o connected dev");
252 
253 	ret = w1_write_read(master_dev, &cfg_1, block_send, 8, block_rcv, 0);
254 	zassert_equal(ret, -ENODEV, "w1_write_read should fail w/o connected dev");
255 }
256 
w1_api_tests_setup(void)257 static void *w1_api_tests_setup(void)
258 {
259 	k_object_access_grant(get_w1_master_dev(), k_current_get());
260 	return NULL;
261 }
262 
263 ZTEST_SUITE(w1_api, NULL, w1_api_tests_setup, NULL, NULL, NULL);
264