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