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
11 #include "common.h"
12
13 /**
14 * @addtogroup t_can_driver
15 * @{
16 * @defgroup t_can_canfd test_can_canfd
17 * @}
18 */
19
tx_std_callback_1(const struct device * dev,int error,void * user_data)20 static void tx_std_callback_1(const struct device *dev, int error, void *user_data)
21 {
22 const struct can_frame *frame = user_data;
23
24 k_sem_give(&tx_callback_sem);
25
26 zassert_equal(dev, can_dev, "CAN device does not match");
27 zassert_equal(frame->id, TEST_CAN_STD_ID_1, "ID does not match");
28 }
29
tx_std_callback_2(const struct device * dev,int error,void * user_data)30 static void tx_std_callback_2(const struct device *dev, int error, void *user_data)
31 {
32 const struct can_frame *frame = user_data;
33
34 k_sem_give(&tx_callback_sem);
35
36 zassert_equal(dev, can_dev, "CAN device does not match");
37 zassert_equal(frame->id, TEST_CAN_STD_ID_2, "ID does not match");
38 }
39
rx_std_callback_1(const struct device * dev,struct can_frame * frame,void * user_data)40 static void rx_std_callback_1(const struct device *dev, struct can_frame *frame, void *user_data)
41 {
42 struct can_filter *filter = user_data;
43
44 assert_frame_equal(frame, &test_std_frame_1, 0);
45 zassert_equal(dev, can_dev, "CAN device does not match");
46 zassert_equal_ptr(filter, &test_std_filter_1, "filter does not match");
47
48 k_sem_give(&rx_callback_sem);
49 }
50
rx_std_callback_2(const struct device * dev,struct can_frame * frame,void * user_data)51 static void rx_std_callback_2(const struct device *dev, struct can_frame *frame, void *user_data)
52 {
53 struct can_filter *filter = user_data;
54
55 assert_frame_equal(frame, &test_std_frame_2, 0);
56 zassert_equal(dev, can_dev, "CAN device does not match");
57 zassert_equal_ptr(filter, &test_std_filter_2, "filter does not match");
58
59 k_sem_give(&rx_callback_sem);
60 }
61
rx_std_callback_fd_1(const struct device * dev,struct can_frame * frame,void * user_data)62 static void rx_std_callback_fd_1(const struct device *dev, struct can_frame *frame,
63 void *user_data)
64 {
65 struct can_filter *filter = user_data;
66
67 assert_frame_equal(frame, &test_std_fdf_frame_1, 0);
68 zassert_equal(dev, can_dev, "CAN device does not match");
69 zassert_equal_ptr(filter, &test_std_filter_1, "filter does not match");
70
71 k_sem_give(&rx_callback_sem);
72 }
73
rx_std_callback_fd_2(const struct device * dev,struct can_frame * frame,void * user_data)74 static void rx_std_callback_fd_2(const struct device *dev, struct can_frame *frame,
75 void *user_data)
76 {
77 struct can_filter *filter = user_data;
78
79 assert_frame_equal(frame, &test_std_fdf_frame_2, 0);
80 zassert_equal(dev, can_dev, "CAN device does not match");
81 zassert_equal_ptr(filter, &test_std_filter_2, "filter does not match");
82
83 k_sem_give(&rx_callback_sem);
84 }
85
86 /**
87 * @brief Send a CAN test frame with asserts.
88 *
89 * This function will block until the frame is transmitted or a test timeout
90 * occurs.
91 *
92 * @param dev Pointer to the device structure for the driver instance.
93 * @param frame Pointer to the CAN frame to send.
94 */
send_test_frame(const struct device * dev,const struct can_frame * frame)95 static void send_test_frame(const struct device *dev, const struct can_frame *frame)
96 {
97 int err;
98
99 err = can_send(dev, frame, TEST_SEND_TIMEOUT, NULL, NULL);
100 zassert_not_equal(err, -EBUSY, "arbitration lost in loopback mode");
101 zassert_equal(err, 0, "failed to send frame (err %d)", err);
102 }
103
104 /**
105 * @brief Send a CAN test frame with asserts.
106 *
107 * This function will block until the frame is queued or a test timeout
108 * occurs.
109 *
110 * @param dev Pointer to the device structure for the driver instance.
111 * @param frame Pointer to the CAN frame to send.
112 * @param callback Transmit callback function.
113 */
send_test_frame_nowait(const struct device * dev,const struct can_frame * frame,can_tx_callback_t callback)114 static void send_test_frame_nowait(const struct device *dev, const struct can_frame *frame,
115 can_tx_callback_t callback)
116 {
117 int err;
118
119 err = can_send(dev, frame, TEST_SEND_TIMEOUT, callback, (void *)frame);
120 zassert_not_equal(err, -EBUSY, "arbitration lost in loopback mode");
121 zassert_equal(err, 0, "failed to send frame (err %d)", err);
122 }
123
124 /**
125 * @brief Add a CAN message queue with asserts.
126 *
127 * @param dev Pointer to the device structure for the driver instance.
128 * @param filter CAN filter for the CAN message queue.
129 *
130 * @return CAN filter ID.
131 */
add_rx_msgq(const struct device * dev,const struct can_filter * filter)132 static inline int add_rx_msgq(const struct device *dev, const struct can_filter *filter)
133 {
134 int filter_id;
135
136 filter_id = can_add_rx_filter_msgq(dev, &can_msgq, filter);
137 zassert_not_equal(filter_id, -ENOSPC, "no filters available");
138 zassert_true(filter_id >= 0, "negative filter number");
139
140 return filter_id;
141 }
142
143 /**
144 * @brief Add a CAN filter with asserts.
145 *
146 * @param dev Pointer to the device structure for the driver instance.
147 * @param filter CAN filter.
148 * @param callback Receive callback function.
149 *
150 * @return CAN filter ID.
151 */
add_rx_filter(const struct device * dev,const struct can_filter * filter,can_rx_callback_t callback)152 static inline int add_rx_filter(const struct device *dev,
153 const struct can_filter *filter,
154 can_rx_callback_t callback)
155 {
156 int filter_id;
157
158 k_sem_reset(&rx_callback_sem);
159
160 filter_id = can_add_rx_filter(dev, callback, (void *)filter, filter);
161 zassert_not_equal(filter_id, -ENOSPC, "no filters available");
162 zassert_true(filter_id >= 0, "negative filter number");
163
164 return filter_id;
165 }
166
167 /**
168 * @brief Perform a send/receive test with a set of CAN ID filters and CAN frames.
169 *
170 * @param filter1 CAN filter 1
171 * @param filter2 CAN filter 2
172 * @param frame1 CAN frame 1
173 * @param frame2 CAN frame 2
174 */
send_receive(const struct can_filter * filter1,const struct can_filter * filter2,const struct can_frame * frame1,const struct can_frame * frame2)175 static void send_receive(const struct can_filter *filter1,
176 const struct can_filter *filter2,
177 const struct can_frame *frame1,
178 const struct can_frame *frame2)
179 {
180 struct can_frame frame_buffer;
181 int filter_id_1;
182 int filter_id_2;
183 int err;
184
185 filter_id_1 = add_rx_msgq(can_dev, filter1);
186 send_test_frame(can_dev, frame1);
187
188 err = k_msgq_get(&can_msgq, &frame_buffer, TEST_RECEIVE_TIMEOUT);
189 zassert_equal(err, 0, "receive timeout");
190
191 assert_frame_equal(&frame_buffer, frame1, 0);
192 can_remove_rx_filter(can_dev, filter_id_1);
193
194 k_sem_reset(&tx_callback_sem);
195
196 if ((frame1->flags & CAN_FRAME_FDF) != 0) {
197 filter_id_1 = add_rx_filter(can_dev, filter1, rx_std_callback_fd_1);
198 } else {
199 filter_id_1 = add_rx_filter(can_dev, filter1, rx_std_callback_1);
200 }
201
202 if ((frame2->flags & CAN_FRAME_FDF) != 0) {
203 filter_id_2 = add_rx_filter(can_dev, filter2, rx_std_callback_fd_2);
204 } else {
205 filter_id_2 = add_rx_filter(can_dev, filter2, rx_std_callback_2);
206 }
207
208 send_test_frame_nowait(can_dev, frame1, tx_std_callback_1);
209 send_test_frame_nowait(can_dev, frame2, tx_std_callback_2);
210
211 err = k_sem_take(&rx_callback_sem, TEST_RECEIVE_TIMEOUT);
212 zassert_equal(err, 0, "receive timeout");
213
214 err = k_sem_take(&rx_callback_sem, TEST_RECEIVE_TIMEOUT);
215 zassert_equal(err, 0, "receive timeout");
216
217 err = k_sem_take(&tx_callback_sem, TEST_SEND_TIMEOUT);
218 zassert_equal(err, 0, "missing TX callback");
219
220 err = k_sem_take(&tx_callback_sem, TEST_SEND_TIMEOUT);
221 zassert_equal(err, 0, "missing TX callback");
222
223 can_remove_rx_filter(can_dev, filter_id_1);
224 can_remove_rx_filter(can_dev, filter_id_2);
225 }
226
227 /**
228 * @brief Test getting the CAN controller capabilities.
229 */
ZTEST(canfd,test_canfd_get_capabilities)230 ZTEST(canfd, test_canfd_get_capabilities)
231 {
232 can_mode_t cap;
233 int err;
234
235 err = can_get_capabilities(can_dev, &cap);
236 zassert_equal(err, 0, "failed to get CAN capabilities (err %d)", err);
237 zassert_not_equal(cap & (CAN_MODE_LOOPBACK | CAN_MODE_FD), 0,
238 "CAN FD loopback mode not supported");
239 }
240
241 /**
242 * @brief Test send/receive with standard (11-bit) CAN IDs and classic CAN frames.
243 */
ZTEST(canfd,test_send_receive_classic)244 ZTEST(canfd, test_send_receive_classic)
245 {
246 send_receive(&test_std_filter_1, &test_std_filter_2,
247 &test_std_frame_1, &test_std_frame_2);
248 }
249
250 /**
251 * @brief Test send/receive with standard (11-bit) CAN IDs and CAN FD frames.
252 */
ZTEST(canfd,test_send_receive_fd)253 ZTEST(canfd, test_send_receive_fd)
254 {
255 send_receive(&test_std_filter_1, &test_std_filter_2,
256 &test_std_fdf_frame_1, &test_std_fdf_frame_2);
257 }
258
259 /**
260 * @brief Test send/receive with (11-bit) CAN IDs, mixed classic and CAN FD frames.
261 */
ZTEST(canfd,test_send_receive_mixed)262 ZTEST(canfd, test_send_receive_mixed)
263 {
264 send_receive(&test_std_filter_1, &test_std_filter_2,
265 &test_std_fdf_frame_1, &test_std_frame_2);
266 }
267
268 /**
269 * @brief Test that CAN RX filters are preserved through CAN controller mode changes.
270 */
check_filters_preserved_between_modes(can_mode_t first,can_mode_t second)271 static void check_filters_preserved_between_modes(can_mode_t first, can_mode_t second)
272 {
273 struct can_frame frame;
274 enum can_state state;
275 int filter_id_1;
276 int filter_id_2;
277 int err;
278
279 /* Stop controller and set first mode */
280 err = can_stop(can_dev);
281 zassert_equal(err, 0, "failed to stop CAN controller (err %d)", err);
282
283 err = can_get_state(can_dev, &state, NULL);
284 zassert_equal(err, 0, "failed to get CAN state (err %d)", err);
285 zassert_equal(state, CAN_STATE_STOPPED, "CAN controller not stopped");
286
287 err = can_set_mode(can_dev, first | CAN_MODE_LOOPBACK);
288 zassert_equal(err, 0, "failed to set first loopback mode (err %d)", err);
289 zassert_equal(first | CAN_MODE_LOOPBACK, can_get_mode(can_dev));
290
291 err = can_start(can_dev);
292 zassert_equal(err, 0, "failed to start CAN controller (err %d)", err);
293
294 /* Add classic CAN and CAN FD filter */
295 filter_id_1 = add_rx_msgq(can_dev, &test_std_filter_1);
296 filter_id_2 = add_rx_msgq(can_dev, &test_std_filter_2);
297
298 /* Verify classic filter in first mode */
299 send_test_frame(can_dev, &test_std_frame_1);
300 err = k_msgq_get(&can_msgq, &frame, TEST_RECEIVE_TIMEOUT);
301 zassert_equal(err, 0, "receive timeout");
302 assert_frame_equal(&frame, &test_std_frame_1, 0);
303
304 if ((first & CAN_MODE_FD) != 0) {
305 /* Verify CAN FD filter in first mode */
306 send_test_frame(can_dev, &test_std_fdf_frame_2);
307 err = k_msgq_get(&can_msgq, &frame, TEST_RECEIVE_TIMEOUT);
308 zassert_equal(err, 0, "receive timeout");
309 assert_frame_equal(&frame, &test_std_fdf_frame_2, 0);
310 }
311
312 /* Stop controller and set second mode */
313 err = can_stop(can_dev);
314 zassert_equal(err, 0, "failed to stop CAN controller (err %d)", err);
315
316 err = can_get_state(can_dev, &state, NULL);
317 zassert_equal(err, 0, "failed to get CAN state (err %d)", err);
318 zassert_equal(state, CAN_STATE_STOPPED, "CAN controller not stopped");
319
320 err = can_set_mode(can_dev, second | CAN_MODE_LOOPBACK);
321 zassert_equal(err, 0, "failed to set second loopback mode (err %d)", err);
322 zassert_equal(second | CAN_MODE_LOOPBACK, can_get_mode(can_dev));
323
324 err = can_start(can_dev);
325 zassert_equal(err, 0, "failed to start CAN controller (err %d)", err);
326
327 /* Verify classic filter in second mode */
328 send_test_frame(can_dev, &test_std_frame_1);
329 err = k_msgq_get(&can_msgq, &frame, TEST_RECEIVE_TIMEOUT);
330 zassert_equal(err, 0, "receive timeout");
331 assert_frame_equal(&frame, &test_std_frame_1, 0);
332
333 if ((second & CAN_MODE_FD) != 0) {
334 /* Verify CAN FD filter in second mode */
335 send_test_frame(can_dev, &test_std_fdf_frame_2);
336 err = k_msgq_get(&can_msgq, &frame, TEST_RECEIVE_TIMEOUT);
337 zassert_equal(err, 0, "receive timeout");
338 assert_frame_equal(&frame, &test_std_fdf_frame_2, 0);
339 }
340
341 /* Stop controller and restore CAN FD loopback mode */
342 err = can_stop(can_dev);
343 zassert_equal(err, 0, "failed to stop CAN controller (err %d)", err);
344
345 err = can_get_state(can_dev, &state, NULL);
346 zassert_equal(err, 0, "failed to get CAN state (err %d)", err);
347 zassert_equal(state, CAN_STATE_STOPPED, "CAN controller not stopped");
348
349 err = can_set_mode(can_dev, CAN_MODE_FD | CAN_MODE_LOOPBACK);
350 zassert_equal(err, 0, "failed to set loopback-mode (err %d)", err);
351 zassert_equal(CAN_MODE_FD | CAN_MODE_LOOPBACK, can_get_mode(can_dev));
352
353 err = can_start(can_dev);
354 zassert_equal(err, 0, "failed to start CAN controller (err %d)", err);
355
356 can_remove_rx_filter(can_dev, filter_id_1);
357 can_remove_rx_filter(can_dev, filter_id_2);
358 }
359
360 /**
361 * @brief Test that CAN RX filters are preserved through CAN controller mode changes between classic
362 * CAN and CAN FD.
363 */
ZTEST_USER(canfd,test_filters_preserved_through_classic_to_fd_mode_change)364 ZTEST_USER(canfd, test_filters_preserved_through_classic_to_fd_mode_change)
365 {
366 check_filters_preserved_between_modes(CAN_MODE_NORMAL, CAN_MODE_FD);
367 }
368
369 /**
370 * @brief Test that CAN RX filters are preserved through CAN controller mode changes between CAN FD
371 * and classic CAN.
372 */
ZTEST_USER(canfd,test_filters_preserved_through_fd_to_classic_mode_change)373 ZTEST_USER(canfd, test_filters_preserved_through_fd_to_classic_mode_change)
374 {
375 check_filters_preserved_between_modes(CAN_MODE_FD, CAN_MODE_NORMAL);
376 }
377
378 /**
379 * @brief Test setting data phase bitrate is not allowed while started.
380 */
ZTEST_USER(canfd,test_set_bitrate_data_while_started)381 ZTEST_USER(canfd, test_set_bitrate_data_while_started)
382 {
383 int err;
384
385 err = can_set_bitrate_data(can_dev, TEST_BITRATE_3);
386 zassert_not_equal(err, 0, "changed data bitrate while started");
387 zassert_equal(err, -EBUSY, "wrong error return code (err %d)", err);
388 }
389
390 /**
391 * @brief Test setting data phase timing is not allowed while started.
392 */
ZTEST_USER(canfd,test_set_timing_data_while_started)393 ZTEST_USER(canfd, test_set_timing_data_while_started)
394 {
395 struct can_timing timing = { 0 };
396 int err;
397
398 err = can_calc_timing_data(can_dev, &timing, TEST_BITRATE_3, TEST_SAMPLE_POINT);
399 zassert_ok(err, "failed to calculate data timing (err %d)", err);
400
401 err = can_set_timing_data(can_dev, &timing);
402 zassert_not_equal(err, 0, "changed data timing while started");
403 zassert_equal(err, -EBUSY, "wrong error return code (err %d)", err);
404 }
405
canfd_predicate(const void * state)406 static bool canfd_predicate(const void *state)
407 {
408 can_mode_t cap;
409 int err;
410
411 ARG_UNUSED(state);
412
413 if (!device_is_ready(can_dev)) {
414 TC_PRINT("CAN device not ready");
415 return false;
416 }
417
418 err = can_get_capabilities(can_dev, &cap);
419 zassert_equal(err, 0, "failed to get CAN controller capabilities (err %d)", err);
420
421 if ((cap & CAN_MODE_FD) == 0) {
422 return false;
423 }
424
425 return true;
426 }
427
canfd_setup(void)428 void *canfd_setup(void)
429 {
430 int err;
431
432 k_sem_init(&rx_callback_sem, 0, 2);
433 k_sem_init(&tx_callback_sem, 0, 2);
434
435 (void)can_stop(can_dev);
436
437 err = can_set_mode(can_dev, CAN_MODE_LOOPBACK | CAN_MODE_FD);
438 zassert_equal(err, 0, "failed to set CAN FD loopback mode (err %d)", err);
439 zassert_equal(CAN_MODE_LOOPBACK | CAN_MODE_FD, can_get_mode(can_dev));
440
441 err = can_start(can_dev);
442 zassert_equal(err, 0, "failed to start CAN controller (err %d)", err);
443
444 return NULL;
445 }
446
447 ZTEST_SUITE(canfd, canfd_predicate, canfd_setup, NULL, NULL, NULL);
448