1 /*
2  * Copyright (c) 2022 Vestas Wind Systems A/S
3  * Copyright (c) 2019 Alexander Wachter
4  *
5  * SPDX-License-Identifier: Apache-2.0
6  */
7 
8 #include <zephyr/drivers/can.h>
9 #include <zephyr/ztest.h>
10 #include <strings.h>
11 
12 /**
13  * @addtogroup t_driver_can
14  * @{
15  * @defgroup t_can_timing test_can_timing
16  * @}
17  */
18 
19 /**
20  * @brief Allowed sample point calculation margin in permille.
21  */
22 #define SAMPLE_POINT_MARGIN 50
23 
24 /**
25  * @brief Defines a set of CAN timing test values
26  */
27 struct can_timing_test {
28 	/** Desired bitrate in bits/s */
29 	uint32_t bitrate;
30 	/** Desired sample point in permille */
31 	uint16_t sp;
32 	/** Do these values represent an invalid CAN timing? */
33 	bool invalid;
34 };
35 
36 /**
37  * @brief List of CAN timing values to test.
38  */
39 static const struct can_timing_test can_timing_tests[] = {
40 	/** Standard bitrates. */
41 #ifndef CONFIG_CAN_ESP32_TWAI
42 	/* ESP32 TWAI does not support bitrates below 25kbit/s */
43 	{   20000, 875, false },
44 #endif /* CONFIG_CAN_ESP32_TWAI */
45 	{   50000, 875, false },
46 	{  125000, 875, false },
47 	{  250000, 875, false },
48 	{  500000, 875, false },
49 	{  800000, 800, false },
50 	{ 1000000, 750, false },
51 	/** Additional, valid sample points. */
52 	{  125000, 900, false },
53 	{  125000, 800, false },
54 	/** Valid bitrate, invalid sample point. */
55 	{  125000, 1000, true },
56 	/** Invalid classic/arbitration bitrate, valid sample point. */
57 	{ 1000000 + 1, 750, true },
58 };
59 
60 /**
61  * @brief List of CAN timing values to test for the data phase.
62  */
63 #ifdef CONFIG_CAN_FD_MODE
64 static const struct can_timing_test can_timing_data_tests[] = {
65 	/** Standard bitrates. */
66 	{  500000, 875, false },
67 	{ 1000000, 750, false },
68 	/** Additional, valid sample points. */
69 	{  500000, 900, false },
70 	{  500000, 800, false },
71 	/** Valid bitrate, invalid sample point. */
72 	{  500000, 1000, true },
73 	/** Invalid CAN-FD bitrate, valid sample point. */
74 	{ 8000000 + 1, 750, true },
75 };
76 #endif /* CONFIG_CAN_FD_MODE */
77 
78 /**
79  * @brief Assert that a CAN timing struct matches the specified bitrate
80  *
81  * Assert that the values of a CAN timing struct matches the specified bitrate
82  * for a given CAN controller device instance.
83  *
84  * @param dev pointer to the device structure for the driver instance
85  * @param timing pointer to the CAN timing struct
86  * @param bitrate the CAN bitrate in bits/s
87  */
assert_bitrate_correct(const struct device * dev,struct can_timing * timing,uint32_t bitrate)88 static void assert_bitrate_correct(const struct device *dev, struct can_timing *timing,
89 				   uint32_t bitrate)
90 {
91 	const uint32_t ts = 1 + timing->prop_seg + timing->phase_seg1 + timing->phase_seg2;
92 	uint32_t core_clock;
93 	uint32_t bitrate_calc;
94 	int err;
95 
96 	zassert_not_equal(timing->prescaler, 0, "prescaler is zero");
97 
98 	err = can_get_core_clock(dev, &core_clock);
99 	zassert_equal(err, 0, "failed to get core CAN clock");
100 
101 	bitrate_calc = core_clock / timing->prescaler / ts;
102 	zassert_equal(bitrate, bitrate_calc, "bitrate mismatch");
103 }
104 
105 /**
106  * @brief Assert that a CAN timing struct is within the bounds
107  *
108  * Assert that the values of a CAN timing struct are within the bounds for a
109  * given CAN controller device instance.
110  *
111  * @param dev pointer to the device structure for the driver instance
112  * @param timing pointer to the CAN timing struct
113  */
assert_timing_within_bounds(struct can_timing * timing,const struct can_timing * min,const struct can_timing * max)114 static void assert_timing_within_bounds(struct can_timing *timing,
115 					const struct can_timing *min,
116 					const struct can_timing *max)
117 {
118 	zassert_true(timing->sjw <= max->sjw, "sjw exceeds max");
119 	zassert_true(timing->prop_seg <= max->prop_seg, "prop_seg exceeds max");
120 	zassert_true(timing->phase_seg1 <= max->phase_seg1, "phase_seg1 exceeds max");
121 	zassert_true(timing->phase_seg2 <= max->phase_seg2, "phase_seg2 exceeds max");
122 	zassert_true(timing->prescaler <= max->prescaler, "prescaler exceeds max");
123 
124 	zassert_true(timing->sjw >= min->sjw, "sjw lower than min");
125 	zassert_true(timing->prop_seg >= min->prop_seg, "prop_seg lower than min");
126 	zassert_true(timing->phase_seg1 >= min->phase_seg1, "phase_seg1 lower than min");
127 	zassert_true(timing->phase_seg2 >= min->phase_seg2, "phase_seg2 lower than min");
128 	zassert_true(timing->prescaler >= min->prescaler, "prescaler lower than min");
129 }
130 
131 /**
132  * @brief Assert that a sample point is within a specified margin
133  *
134  * Assert that values of a CAN timing struct results in a specified sample point
135  * within a given margin.
136  *
137  * @param timing pointer to the CAN timing struct
138  * @param sp sample point in permille
139  * @param sp_margin sample point margin in permille
140  */
assert_sp_within_margin(struct can_timing * timing,uint16_t sp,uint16_t sp_margin)141 static void assert_sp_within_margin(struct can_timing *timing, uint16_t sp, uint16_t sp_margin)
142 {
143 	const uint32_t ts = 1 + timing->prop_seg + timing->phase_seg1 + timing->phase_seg2;
144 	const uint16_t sp_calc = ((1 + timing->prop_seg + timing->phase_seg1) * 1000) / ts;
145 
146 	zassert_within(sp, sp_calc, sp_margin,
147 		       "sample point %d not within calculated sample point %d +/- %d",
148 		       sp, sp_calc, sp_margin);
149 }
150 
151 /**
152  * @brief Test a set of CAN timing values
153  *
154  * Test a set of CAN timing values on a specified CAN controller device
155  * instance.
156  *
157  * @param dev pointer to the device structure for the driver instance
158  * @param test pointer to the set of CAN timing values
159  */
test_timing_values(const struct device * dev,const struct can_timing_test * test,bool data_phase)160 static void test_timing_values(const struct device *dev, const struct can_timing_test *test,
161 			       bool data_phase)
162 {
163 	const struct can_timing *max = NULL;
164 	const struct can_timing *min = NULL;
165 	struct can_timing timing = { 0 };
166 	int sp_err;
167 	int err;
168 
169 	printk("testing bitrate %u, sample point %u.%u%% (%s): ",
170 		test->bitrate, test->sp / 10, test->sp % 10, test->invalid ? "invalid" : "valid");
171 
172 	if (data_phase) {
173 		if (IS_ENABLED(CONFIG_CAN_FD_MODE)) {
174 			min = can_get_timing_data_min(dev);
175 			max = can_get_timing_data_max(dev);
176 			sp_err = can_calc_timing_data(dev, &timing, test->bitrate, test->sp);
177 		} else {
178 			zassert_unreachable("data phase timing test without CAN-FD support");
179 		}
180 	} else {
181 		min = can_get_timing_min(dev);
182 		max = can_get_timing_max(dev);
183 		sp_err = can_calc_timing(dev, &timing, test->bitrate, test->sp);
184 	}
185 
186 	if (test->invalid) {
187 		zassert_equal(sp_err, -EINVAL, "err %d, expected -EINVAL", sp_err);
188 		printk("OK\n");
189 	} else {
190 		zassert_true(sp_err >= 0, "unknown error %d", sp_err);
191 		zassert_true(sp_err <= SAMPLE_POINT_MARGIN, "sample point error %d too large",
192 			     sp_err);
193 
194 		printk("sjw = %u, prop_seg = %u, phase_seg1 = %u, phase_seg2 = %u, prescaler = %u ",
195 			timing.sjw, timing.prop_seg, timing.phase_seg1, timing.phase_seg2,
196 			timing.prescaler);
197 
198 		assert_bitrate_correct(dev, &timing, test->bitrate);
199 		assert_timing_within_bounds(&timing, min, max);
200 		assert_sp_within_margin(&timing, test->sp, SAMPLE_POINT_MARGIN);
201 
202 		if (IS_ENABLED(CONFIG_CAN_FD_MODE) && data_phase) {
203 			err = can_set_timing_data(dev, &timing);
204 		} else {
205 			err = can_set_timing(dev, &timing);
206 		}
207 		zassert_equal(err, 0, "failed to set timing (err %d)", err);
208 
209 		printk("OK, sample point error %d.%d%%\n", sp_err / 10, sp_err % 10);
210 	}
211 }
212 
213 /**
214  * @brief Test all CAN timing values
215  */
ZTEST_USER(can_timing,test_timing)216 ZTEST_USER(can_timing, test_timing)
217 {
218 	const struct device *const dev = DEVICE_DT_GET(DT_CHOSEN(zephyr_canbus));
219 	int i;
220 
221 	for (i = 0; i < ARRAY_SIZE(can_timing_tests); i++) {
222 		test_timing_values(dev, &can_timing_tests[i], false);
223 	}
224 }
225 
226 /**
227  * @brief Test all CAN timing values for the data phase.
228  */
ZTEST_USER(can_timing,test_timing_data)229 ZTEST_USER(can_timing, test_timing_data)
230 {
231 	const struct device *const dev = DEVICE_DT_GET(DT_CHOSEN(zephyr_canbus));
232 	can_mode_t cap;
233 	int err;
234 	int i;
235 
236 	err = can_get_capabilities(dev, &cap);
237 	zassert_equal(err, 0, "failed to get CAN controller capabilities (err %d)", err);
238 
239 	if ((cap & CAN_MODE_FD) == 0) {
240 		ztest_test_skip();
241 	}
242 
243 	for (i = 0; i < ARRAY_SIZE(can_timing_data_tests); i++) {
244 		test_timing_values(dev, &can_timing_data_tests[i], true);
245 	}
246 }
247 
248 /**
249  * @brief Test that the minimum timing values can be set.
250  */
ZTEST_USER(can_timing,test_set_timing_min)251 ZTEST_USER(can_timing, test_set_timing_min)
252 {
253 	const struct device *const dev = DEVICE_DT_GET(DT_CHOSEN(zephyr_canbus));
254 	int err;
255 
256 	err = can_set_timing(dev, can_get_timing_min(dev));
257 	zassert_equal(err, 0, "failed to set minimum timing parameters (err %d)", err);
258 }
259 
260 /**
261  * @brief Test that the minimum timing values for the data phase can be set.
262  */
ZTEST_USER(can_timing,test_set_timing_data_min)263 ZTEST_USER(can_timing, test_set_timing_data_min)
264 {
265 	const struct device *const dev = DEVICE_DT_GET(DT_CHOSEN(zephyr_canbus));
266 	can_mode_t cap;
267 	int err;
268 
269 	err = can_get_capabilities(dev, &cap);
270 	zassert_equal(err, 0, "failed to get CAN controller capabilities (err %d)", err);
271 
272 	if ((cap & CAN_MODE_FD) == 0) {
273 		ztest_test_skip();
274 	}
275 
276 	err = can_set_timing_data(dev, can_get_timing_data_min(dev));
277 	zassert_equal(err, 0, "failed to set minimum timing data parameters (err %d)", err);
278 }
279 
280 /**
281  * @brief Test that the maximum timing values can be set.
282  */
ZTEST_USER(can_timing,test_set_timing_max)283 ZTEST_USER(can_timing, test_set_timing_max)
284 {
285 	const struct device *const dev = DEVICE_DT_GET(DT_CHOSEN(zephyr_canbus));
286 	int err;
287 
288 	err = can_set_timing(dev, can_get_timing_max(dev));
289 	zassert_equal(err, 0, "failed to set maximum timing parameters (err %d)", err);
290 }
291 
292 /**
293  * @brief Test that the maximum timing values for the data phase can be set.
294  */
ZTEST_USER(can_timing,test_set_timing_data_max)295 ZTEST_USER(can_timing, test_set_timing_data_max)
296 {
297 	const struct device *const dev = DEVICE_DT_GET(DT_CHOSEN(zephyr_canbus));
298 	can_mode_t cap;
299 	int err;
300 
301 	err = can_get_capabilities(dev, &cap);
302 	zassert_equal(err, 0, "failed to get CAN controller capabilities (err %d)", err);
303 
304 	if ((cap & CAN_MODE_FD) == 0) {
305 		ztest_test_skip();
306 	}
307 
308 	err = can_set_timing_data(dev, can_get_timing_data_max(dev));
309 	zassert_equal(err, 0, "failed to set maximum timing data parameters (err %d)", err);
310 }
311 
can_timing_setup(void)312 void *can_timing_setup(void)
313 {
314 	const struct device *const dev = DEVICE_DT_GET(DT_CHOSEN(zephyr_canbus));
315 	uint32_t core_clock;
316 	int err;
317 
318 	zassert_true(device_is_ready(dev), "CAN device not ready");
319 
320 	err = can_get_core_clock(dev, &core_clock);
321 	zassert_equal(err, 0, "failed to get core CAN clock");
322 
323 	printk("testing on device %s @ %u Hz\n", dev->name, core_clock);
324 
325 	k_object_access_grant(dev, k_current_get());
326 
327 	return NULL;
328 }
329 
330 ZTEST_SUITE(can_timing, NULL, can_timing_setup, NULL, NULL, NULL);
331