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 <stdlib.h>
9 #include <stdio.h>
10 
11 #include <zephyr/device.h>
12 #include <zephyr/drivers/can.h>
13 #include <zephyr/logging/log.h>
14 #include <zephyr/shell/shell.h>
15 
16 LOG_MODULE_REGISTER(can_shell, CONFIG_CAN_LOG_LEVEL);
17 
18 struct can_shell_tx_event {
19 	unsigned int frame_no;
20 	int error;
21 };
22 
23 struct can_shell_mode_mapping {
24 	const char *name;
25 	can_mode_t mode;
26 };
27 
28 #define CAN_SHELL_MODE_MAPPING(_name, _mode) { .name = _name, .mode = _mode }
29 
30 static const struct can_shell_mode_mapping can_shell_mode_map[] = {
31 	/* Array sorted alphabetically based on name */
32 	CAN_SHELL_MODE_MAPPING("fd",              CAN_MODE_FD),
33 	CAN_SHELL_MODE_MAPPING("listen-only",     CAN_MODE_LISTENONLY),
34 	CAN_SHELL_MODE_MAPPING("loopback",        CAN_MODE_LOOPBACK),
35 	CAN_SHELL_MODE_MAPPING("normal",          CAN_MODE_NORMAL),
36 	CAN_SHELL_MODE_MAPPING("one-shot",        CAN_MODE_ONE_SHOT),
37 	CAN_SHELL_MODE_MAPPING("triple-sampling", CAN_MODE_3_SAMPLES),
38 };
39 
40 K_MSGQ_DEFINE(can_shell_tx_msgq, sizeof(struct can_shell_tx_event),
41 	      CONFIG_CAN_SHELL_TX_QUEUE_SIZE, 4);
42 const struct shell *can_shell_tx_msgq_sh;
43 static struct k_work_poll can_shell_tx_msgq_work;
44 static struct k_poll_event can_shell_tx_msgq_events[] = {
45 	K_POLL_EVENT_STATIC_INITIALIZER(K_POLL_TYPE_MSGQ_DATA_AVAILABLE,
46 					K_POLL_MODE_NOTIFY_ONLY,
47 					&can_shell_tx_msgq, 0)
48 };
49 
50 CAN_MSGQ_DEFINE(can_shell_rx_msgq, CONFIG_CAN_SHELL_RX_QUEUE_SIZE);
51 const struct shell *can_shell_rx_msgq_sh;
52 static struct k_work_poll can_shell_rx_msgq_work;
53 static struct k_poll_event can_shell_rx_msgq_events[] = {
54 	K_POLL_EVENT_STATIC_INITIALIZER(K_POLL_TYPE_MSGQ_DATA_AVAILABLE,
55 					K_POLL_MODE_NOTIFY_ONLY,
56 					&can_shell_rx_msgq, 0)
57 };
58 
59 /* Forward declarations */
60 static void can_shell_tx_msgq_triggered_work_handler(struct k_work *work);
61 static void can_shell_rx_msgq_triggered_work_handler(struct k_work *work);
62 
can_shell_print_frame(const struct shell * sh,const struct can_frame * frame)63 static void can_shell_print_frame(const struct shell *sh, const struct can_frame *frame)
64 {
65 	uint8_t nbytes = can_dlc_to_bytes(frame->dlc);
66 	int i;
67 
68 #ifdef CONFIG_CAN_RX_TIMESTAMP
69 	/* Timestamp */
70 	shell_fprintf(sh, SHELL_NORMAL, "(%05d)  ", frame->timestamp);
71 #endif /* CONFIG_CAN_RX_TIMESTAMP */
72 
73 #ifdef CONFIG_CAN_FD_MODE
74 	/* Flags */
75 	shell_fprintf(sh, SHELL_NORMAL, "%c%c  ",
76 		      (frame->flags & CAN_FRAME_BRS) == 0 ? '-' : 'B',
77 		      (frame->flags & CAN_FRAME_ESI) == 0 ? '-' : 'P');
78 #endif /* CONFIG_CAN_FD_MODE */
79 
80 	/* CAN ID */
81 	shell_fprintf(sh, SHELL_NORMAL, "%*s%0*x  ",
82 		(frame->flags & CAN_FRAME_IDE) != 0 ? 0 : 5, "",
83 		(frame->flags & CAN_FRAME_IDE) != 0 ? 8 : 3,
84 		(frame->flags & CAN_FRAME_IDE) != 0 ?
85 		frame->id & CAN_EXT_ID_MASK : frame->id & CAN_STD_ID_MASK);
86 
87 	/* DLC as number of bytes */
88 	shell_fprintf(sh, SHELL_NORMAL, "%s[%0*d]  ",
89 		(frame->flags & CAN_FRAME_FDF) != 0 ? "" : " ",
90 		(frame->flags & CAN_FRAME_FDF) != 0 ? 2 : 1,
91 		nbytes);
92 
93 	/* Data payload */
94 	if ((frame->flags & CAN_FRAME_RTR) != 0) {
95 		shell_fprintf(sh, SHELL_NORMAL, "remote transmission request");
96 	} else {
97 		for (i = 0; i < nbytes; i++) {
98 			shell_fprintf(sh, SHELL_NORMAL, "%02x ", frame->data[i]);
99 		}
100 	}
101 
102 	shell_fprintf(sh, SHELL_NORMAL, "\n");
103 }
104 
can_shell_tx_msgq_poll_submit(const struct shell * sh)105 static int can_shell_tx_msgq_poll_submit(const struct shell *sh)
106 {
107 	int err;
108 
109 	if (can_shell_tx_msgq_sh == NULL) {
110 		can_shell_tx_msgq_sh = sh;
111 		k_work_poll_init(&can_shell_tx_msgq_work, can_shell_tx_msgq_triggered_work_handler);
112 	}
113 
114 	err = k_work_poll_submit(&can_shell_tx_msgq_work, can_shell_tx_msgq_events,
115 				 ARRAY_SIZE(can_shell_tx_msgq_events), K_FOREVER);
116 	if (err != 0) {
117 		shell_error(can_shell_tx_msgq_sh, "failed to submit tx msgq polling (err %d)",
118 			    err);
119 	}
120 
121 	return err;
122 }
123 
can_shell_tx_msgq_triggered_work_handler(struct k_work * work)124 static void can_shell_tx_msgq_triggered_work_handler(struct k_work *work)
125 {
126 	struct can_shell_tx_event event;
127 
128 	while (k_msgq_get(&can_shell_tx_msgq, &event, K_NO_WAIT) == 0) {
129 		if (event.error == 0) {
130 			shell_print(can_shell_tx_msgq_sh, "CAN frame #%u successfully sent",
131 				    event.frame_no);
132 		} else {
133 			shell_error(can_shell_tx_msgq_sh, "failed to send CAN frame #%u (err %d)",
134 				    event.frame_no, event.error);
135 		}
136 	}
137 
138 	(void)can_shell_tx_msgq_poll_submit(can_shell_tx_msgq_sh);
139 }
140 
can_shell_tx_callback(const struct device * dev,int error,void * user_data)141 static void can_shell_tx_callback(const struct device *dev, int error, void *user_data)
142 {
143 	struct can_shell_tx_event event;
144 	int err;
145 
146 	ARG_UNUSED(dev);
147 
148 	event.frame_no = POINTER_TO_UINT(user_data);
149 	event.error = error;
150 
151 	err = k_msgq_put(&can_shell_tx_msgq, &event, K_NO_WAIT);
152 	if (err != 0) {
153 		LOG_ERR("CAN shell tx event queue full");
154 	}
155 }
156 
can_shell_rx_msgq_poll_submit(const struct shell * sh)157 static int can_shell_rx_msgq_poll_submit(const struct shell *sh)
158 {
159 	int err;
160 
161 	if (can_shell_rx_msgq_sh == NULL) {
162 		can_shell_rx_msgq_sh = sh;
163 		k_work_poll_init(&can_shell_rx_msgq_work, can_shell_rx_msgq_triggered_work_handler);
164 	}
165 
166 	err = k_work_poll_submit(&can_shell_rx_msgq_work, can_shell_rx_msgq_events,
167 				 ARRAY_SIZE(can_shell_rx_msgq_events), K_FOREVER);
168 	if (err != 0) {
169 		shell_error(can_shell_rx_msgq_sh, "failed to submit rx msgq polling (err %d)",
170 			    err);
171 	}
172 
173 	return err;
174 }
175 
can_shell_rx_msgq_triggered_work_handler(struct k_work * work)176 static void can_shell_rx_msgq_triggered_work_handler(struct k_work *work)
177 {
178 	struct can_frame frame;
179 
180 	while (k_msgq_get(&can_shell_rx_msgq, &frame, K_NO_WAIT) == 0) {
181 		can_shell_print_frame(can_shell_rx_msgq_sh, &frame);
182 	}
183 
184 	(void)can_shell_rx_msgq_poll_submit(can_shell_rx_msgq_sh);
185 }
186 
can_shell_state_to_string(enum can_state state)187 static const char *can_shell_state_to_string(enum can_state state)
188 {
189 	switch (state) {
190 	case CAN_STATE_ERROR_ACTIVE:
191 		return "error-active";
192 	case CAN_STATE_ERROR_WARNING:
193 		return "error-warning";
194 	case CAN_STATE_ERROR_PASSIVE:
195 		return "error-passive";
196 	case CAN_STATE_BUS_OFF:
197 		return "bus-off";
198 	case CAN_STATE_STOPPED:
199 		return "stopped";
200 	default:
201 		return "unknown";
202 	}
203 }
204 
can_shell_print_capabilities(const struct shell * sh,can_mode_t cap)205 static void can_shell_print_capabilities(const struct shell *sh, can_mode_t cap)
206 {
207 	int bit;
208 	int i;
209 
210 	for (bit = 0; bit < sizeof(cap) * 8; bit++) {
211 		/* Skip unset bits */
212 		if ((cap & BIT(bit)) == 0) {
213 			continue;
214 		}
215 
216 		/* Lookup symbolic mode name */
217 		for (i = 0; i < ARRAY_SIZE(can_shell_mode_map); i++) {
218 			if (BIT(bit) == can_shell_mode_map[i].mode) {
219 				shell_fprintf(sh, SHELL_NORMAL, "%s ", can_shell_mode_map[i].name);
220 				break;
221 			}
222 		}
223 
224 		if (i == ARRAY_SIZE(can_shell_mode_map)) {
225 			/* Symbolic name not found, use raw mode */
226 			shell_fprintf(sh, SHELL_NORMAL, "0x%08x ", (can_mode_t)BIT(bit));
227 		}
228 	}
229 }
230 
cmd_can_start(const struct shell * sh,size_t argc,char ** argv)231 static int cmd_can_start(const struct shell *sh, size_t argc, char **argv)
232 {
233 	const struct device *dev = device_get_binding(argv[1]);
234 	int err;
235 
236 	if (!device_is_ready(dev)) {
237 		shell_error(sh, "device %s not ready", argv[1]);
238 		return -ENODEV;
239 	}
240 
241 	shell_print(sh, "starting %s", argv[1]);
242 
243 	err = can_start(dev);
244 	if (err != 0) {
245 		shell_error(sh, "failed to start CAN controller (err %d)", err);
246 		return err;
247 	}
248 
249 	return 0;
250 }
251 
cmd_can_stop(const struct shell * sh,size_t argc,char ** argv)252 static int cmd_can_stop(const struct shell *sh, size_t argc, char **argv)
253 {
254 	const struct device *dev = device_get_binding(argv[1]);
255 	int err;
256 
257 	if (!device_is_ready(dev)) {
258 		shell_error(sh, "device %s not ready", argv[1]);
259 		return -ENODEV;
260 	}
261 
262 	shell_print(sh, "stopping %s", argv[1]);
263 
264 	err = can_stop(dev);
265 	if (err != 0) {
266 		shell_error(sh, "failed to stop CAN controller (err %d)", err);
267 		return err;
268 	}
269 
270 	return 0;
271 }
272 
cmd_can_show(const struct shell * sh,size_t argc,char ** argv)273 static int cmd_can_show(const struct shell *sh, size_t argc, char **argv)
274 {
275 	const struct device *dev = device_get_binding(argv[1]);
276 	const struct can_timing *timing_min;
277 	const struct can_timing *timing_max;
278 	struct can_bus_err_cnt err_cnt;
279 	enum can_state state;
280 	uint32_t max_bitrate = 0;
281 	int max_std_filters = 0;
282 	int max_ext_filters = 0;
283 	uint32_t core_clock;
284 	can_mode_t cap;
285 	int err;
286 
287 	if (!device_is_ready(dev)) {
288 		shell_error(sh, "device %s not ready", argv[1]);
289 		return -ENODEV;
290 	}
291 
292 	err = can_get_core_clock(dev, &core_clock);
293 	if (err != 0) {
294 		shell_error(sh, "failed to get CAN core clock (err %d)", err);
295 		return err;
296 	}
297 
298 	err = can_get_max_bitrate(dev, &max_bitrate);
299 	if (err != 0 && err != -ENOSYS) {
300 		shell_error(sh, "failed to get maximum bitrate (err %d)", err);
301 		return err;
302 	}
303 
304 	max_std_filters = can_get_max_filters(dev, false);
305 	if (max_std_filters < 0 && max_std_filters != -ENOSYS) {
306 		shell_error(sh, "failed to get maximum standard (11-bit) filters (err %d)", err);
307 		return err;
308 	}
309 
310 	max_ext_filters = can_get_max_filters(dev, true);
311 	if (max_ext_filters < 0 && max_ext_filters != -ENOSYS) {
312 		shell_error(sh, "failed to get maximum extended (29-bit) filters (err %d)", err);
313 		return err;
314 	}
315 
316 	err = can_get_capabilities(dev, &cap);
317 	if (err != 0) {
318 		shell_error(sh, "failed to get CAN controller capabilities (err %d)", err);
319 		return err;
320 	}
321 
322 	err = can_get_state(dev, &state, &err_cnt);
323 	if (err != 0) {
324 		shell_error(sh, "failed to get CAN controller state (%d)", err);
325 		return err;
326 	}
327 
328 	shell_print(sh, "core clock:      %d Hz", core_clock);
329 	shell_print(sh, "max bitrate:     %d bps", max_bitrate);
330 	shell_print(sh, "max std filters: %d", max_std_filters);
331 	shell_print(sh, "max ext filters: %d", max_ext_filters);
332 
333 	shell_fprintf(sh, SHELL_NORMAL, "capabilities:    normal ");
334 	can_shell_print_capabilities(sh, cap);
335 	shell_fprintf(sh, SHELL_NORMAL, "\n");
336 
337 	shell_print(sh, "state:           %s", can_shell_state_to_string(state));
338 	shell_print(sh, "rx errors:       %d", err_cnt.rx_err_cnt);
339 	shell_print(sh, "tx errors:       %d", err_cnt.tx_err_cnt);
340 
341 	timing_min = can_get_timing_min(dev);
342 	timing_max = can_get_timing_max(dev);
343 
344 	shell_print(sh, "timing:          sjw %u..%u, prop_seg %u..%u, "
345 		    "phase_seg1 %u..%u, phase_seg2 %u..%u, prescaler %u..%u",
346 		    timing_min->sjw, timing_max->sjw,
347 		    timing_min->prop_seg, timing_max->prop_seg,
348 		    timing_min->phase_seg1, timing_max->phase_seg1,
349 		    timing_min->phase_seg2, timing_max->phase_seg2,
350 		    timing_min->prescaler, timing_max->prescaler);
351 
352 	if (IS_ENABLED(CONFIG_CAN_FD_MODE) && (cap & CAN_MODE_FD) != 0) {
353 		timing_min = can_get_timing_data_min(dev);
354 		timing_max = can_get_timing_data_max(dev);
355 
356 		shell_print(sh, "timing data:     sjw %u..%u, prop_seg %u..%u, "
357 			    "phase_seg1 %u..%u, phase_seg2 %u..%u, prescaler %u..%u",
358 			    timing_min->sjw, timing_max->sjw,
359 			    timing_min->prop_seg, timing_max->prop_seg,
360 			    timing_min->phase_seg1, timing_max->phase_seg1,
361 			    timing_min->phase_seg2, timing_max->phase_seg2,
362 			    timing_min->prescaler, timing_max->prescaler);
363 	}
364 
365 	return 0;
366 }
367 
cmd_can_bitrate_set(const struct shell * sh,size_t argc,char ** argv)368 static int cmd_can_bitrate_set(const struct shell *sh, size_t argc, char **argv)
369 {
370 	const struct device *dev = device_get_binding(argv[1]);
371 	struct can_timing timing = { 0 };
372 	uint16_t sample_pnt;
373 	uint32_t bitrate;
374 	char *endptr;
375 	int err;
376 
377 	if (!device_is_ready(dev)) {
378 		shell_error(sh, "device %s not ready", argv[1]);
379 		return -ENODEV;
380 	}
381 
382 	bitrate = (uint32_t)strtoul(argv[2], &endptr, 10);
383 	if (*endptr != '\0') {
384 		shell_error(sh, "failed to parse bitrate");
385 		return -EINVAL;
386 	}
387 
388 	if (argc >= 4) {
389 		sample_pnt = (uint32_t)strtoul(argv[3], &endptr, 10);
390 		if (*endptr != '\0') {
391 			shell_error(sh, "failed to parse sample point");
392 			return -EINVAL;
393 		}
394 
395 		err = can_calc_timing(dev, &timing, bitrate, sample_pnt);
396 		if (err < 0) {
397 			shell_error(sh, "failed to calculate timing for "
398 				    "bitrate %d bps, sample point %d.%d%% (err %d)",
399 				    bitrate, sample_pnt / 10, sample_pnt % 10, err);
400 			return err;
401 		}
402 
403 		if (argc >= 5) {
404 			/* Overwrite calculated default SJW with user-provided value */
405 			timing.sjw = (uint16_t)strtoul(argv[4], &endptr, 10);
406 			if (*endptr != '\0') {
407 				shell_error(sh, "failed to parse SJW");
408 				return -EINVAL;
409 			}
410 		}
411 
412 		shell_print(sh, "setting bitrate to %d bps, sample point %d.%d%% "
413 			    "(+/- %d.%d%%), sjw %d",
414 			    bitrate, sample_pnt / 10, sample_pnt % 10, err / 10, err % 10,
415 			    timing.sjw);
416 
417 		LOG_DBG("sjw %u, prop_seg %u, phase_seg1 %u, phase_seg2 %u, prescaler %u",
418 			timing.sjw, timing.prop_seg, timing.phase_seg1, timing.phase_seg2,
419 			timing.prescaler);
420 
421 		err = can_set_timing(dev, &timing);
422 		if (err != 0) {
423 			shell_error(sh, "failed to set timing (err %d)", err);
424 			return err;
425 		}
426 	} else {
427 		shell_print(sh, "setting bitrate to %d bps", bitrate);
428 
429 		err = can_set_bitrate(dev, bitrate);
430 		if (err != 0) {
431 			shell_error(sh, "failed to set bitrate (err %d)", err);
432 			return err;
433 		}
434 	}
435 
436 	return 0;
437 }
438 
cmd_can_dbitrate_set(const struct shell * sh,size_t argc,char ** argv)439 static int cmd_can_dbitrate_set(const struct shell *sh, size_t argc, char **argv)
440 {
441 	const struct device *dev = device_get_binding(argv[1]);
442 	struct can_timing timing = { 0 };
443 	uint16_t sample_pnt;
444 	uint32_t bitrate;
445 	char *endptr;
446 	int err;
447 
448 	if (!device_is_ready(dev)) {
449 		shell_error(sh, "device %s not ready", argv[1]);
450 		return -ENODEV;
451 	}
452 
453 	bitrate = (uint32_t)strtoul(argv[2], &endptr, 10);
454 	if (*endptr != '\0') {
455 		shell_error(sh, "failed to parse data bitrate");
456 		return -EINVAL;
457 	}
458 
459 	if (argc >= 4) {
460 		sample_pnt = (uint32_t)strtoul(argv[3], &endptr, 10);
461 		if (*endptr != '\0') {
462 			shell_error(sh, "failed to parse sample point");
463 			return -EINVAL;
464 		}
465 
466 		err = can_calc_timing_data(dev, &timing, bitrate, sample_pnt);
467 		if (err < 0) {
468 			shell_error(sh, "failed to calculate timing for "
469 				    "data bitrate %d bps, sample point %d.%d%% (err %d)",
470 				    bitrate, sample_pnt / 10, sample_pnt % 10, err);
471 			return err;
472 		}
473 
474 		if (argc >= 5) {
475 			/* Overwrite calculated default SJW with user-provided value */
476 			timing.sjw = (uint16_t)strtoul(argv[4], &endptr, 10);
477 			if (*endptr != '\0') {
478 				shell_error(sh, "failed to parse SJW");
479 				return -EINVAL;
480 			}
481 		}
482 
483 		shell_print(sh, "setting data bitrate to %d bps, sample point %d.%d%% "
484 			    "(+/- %d.%d%%), sjw %d",
485 			    bitrate, sample_pnt / 10, sample_pnt % 10, err / 10, err % 10,
486 			    timing.sjw);
487 
488 		LOG_DBG("sjw %u, prop_seg %u, phase_seg1 %u, phase_seg2 %u, prescaler %u",
489 			timing.sjw, timing.prop_seg, timing.phase_seg1, timing.phase_seg2,
490 			timing.prescaler);
491 
492 		err = can_set_timing_data(dev, &timing);
493 		if (err != 0) {
494 			shell_error(sh, "failed to set data timing (err %d)", err);
495 			return err;
496 		}
497 	} else {
498 		shell_print(sh, "setting data bitrate to %d bps", bitrate);
499 
500 		err = can_set_bitrate_data(dev, bitrate);
501 		if (err != 0) {
502 			shell_error(sh, "failed to set data bitrate (err %d)", err);
503 			return err;
504 		}
505 	}
506 
507 	return 0;
508 }
509 
cmd_can_mode_set(const struct shell * sh,size_t argc,char ** argv)510 static int cmd_can_mode_set(const struct shell *sh, size_t argc, char **argv)
511 {
512 	const struct device *dev = device_get_binding(argv[1]);
513 	can_mode_t mode = CAN_MODE_NORMAL;
514 	can_mode_t raw;
515 	char *endptr;
516 	int err;
517 	int i;
518 	int j;
519 
520 	if (!device_is_ready(dev)) {
521 		shell_error(sh, "device %s not ready", argv[1]);
522 		return -ENODEV;
523 	}
524 
525 	for (i = 2; i < argc; i++) {
526 		/* Lookup symbolic mode name */
527 		for (j = 0; j < ARRAY_SIZE(can_shell_mode_map); j++) {
528 			if (strcmp(argv[i], can_shell_mode_map[j].name) == 0) {
529 				mode |= can_shell_mode_map[j].mode;
530 				break;
531 			}
532 		}
533 
534 		if (j == ARRAY_SIZE(can_shell_mode_map)) {
535 			/* Symbolic name not found, use raw mode if hex number */
536 			raw = (can_mode_t)strtoul(argv[i], &endptr, 16);
537 			if (*endptr == '\0') {
538 				mode |= raw;
539 				continue;
540 			}
541 
542 			shell_error(sh, "failed to parse mode");
543 			return -EINVAL;
544 		}
545 	}
546 
547 	shell_print(sh, "setting mode 0x%08x", mode);
548 
549 	err = can_set_mode(dev, mode);
550 	if (err != 0) {
551 		shell_error(sh, "failed to set mode 0x%08x (err %d)", mode, err);
552 		return err;
553 	}
554 
555 	return 0;
556 }
557 
cmd_can_send(const struct shell * sh,size_t argc,char ** argv)558 static int cmd_can_send(const struct shell *sh, size_t argc, char **argv)
559 {
560 	const struct device *dev = device_get_binding(argv[1]);
561 	static unsigned int frame_counter;
562 	unsigned int frame_no;
563 	struct can_frame frame;
564 	uint32_t max_id;
565 	int argidx = 2;
566 	uint32_t val;
567 	char *endptr;
568 	int nbytes;
569 	int err;
570 	int i;
571 
572 	if (!device_is_ready(dev)) {
573 		shell_error(sh, "device %s not ready", argv[1]);
574 		return -ENODEV;
575 	}
576 
577 	/* Defaults */
578 	max_id = CAN_MAX_STD_ID;
579 	frame.flags = 0;
580 	frame.dlc = 0;
581 
582 	/* Parse options */
583 	while (argidx < argc && strncmp(argv[argidx], "-", 1) == 0) {
584 		if (strcmp(argv[argidx], "--") == 0) {
585 			argidx++;
586 			break;
587 		} else if (strcmp(argv[argidx], "-e") == 0) {
588 			frame.flags |= CAN_FRAME_IDE;
589 			max_id = CAN_MAX_EXT_ID;
590 			argidx++;
591 		} else if (strcmp(argv[argidx], "-r") == 0) {
592 			frame.flags |= CAN_FRAME_RTR;
593 			argidx++;
594 		} else if (strcmp(argv[argidx], "-f") == 0) {
595 			frame.flags |= CAN_FRAME_FDF;
596 			argidx++;
597 		} else if (strcmp(argv[argidx], "-b") == 0) {
598 			frame.flags |= CAN_FRAME_BRS;
599 			argidx++;
600 		} else {
601 			shell_error(sh, "unsupported option %s", argv[argidx]);
602 			shell_help(sh);
603 			return SHELL_CMD_HELP_PRINTED;
604 		}
605 	}
606 
607 	/* Parse CAN ID */
608 	if (argidx >= argc) {
609 		shell_error(sh, "missing CAN ID parameter");
610 		shell_help(sh);
611 		return SHELL_CMD_HELP_PRINTED;
612 	}
613 
614 	val = (uint32_t)strtoul(argv[argidx++], &endptr, 16);
615 	if (*endptr != '\0') {
616 		shell_error(sh, "failed to parse CAN ID");
617 		return -EINVAL;
618 	}
619 
620 	if (val > max_id) {
621 		shell_error(sh, "CAN ID 0x%0*x out of range",
622 			    (frame.flags & CAN_FRAME_IDE) != 0 ? 8 : 3,
623 			    val);
624 		return -EINVAL;
625 	}
626 
627 	frame.id = val;
628 
629 	nbytes = argc - argidx;
630 	if (nbytes > ARRAY_SIZE(frame.data)) {
631 		shell_error(sh, "excessive amount of data (%d bytes)", nbytes);
632 		return -EINVAL;
633 	}
634 
635 	frame.dlc = can_bytes_to_dlc(nbytes);
636 
637 	/* Parse data */
638 	for (i = 0; i < nbytes; i++) {
639 		val = (uint32_t)strtoul(argv[argidx++], &endptr, 16);
640 		if (*endptr != '\0') {
641 			shell_error(sh, "failed to parse data %s", argv[argidx++]);
642 			return -EINVAL;
643 		}
644 
645 		if (val > 0xff) {
646 			shell_error(sh, "data 0x%x out of range", val);
647 			return -EINVAL;
648 		}
649 
650 		frame.data[i] = val;
651 	}
652 
653 	err = can_shell_tx_msgq_poll_submit(sh);
654 	if (err != 0) {
655 		return err;
656 	}
657 
658 	frame_no = frame_counter++;
659 
660 	shell_print(sh, "enqueuing CAN frame #%u with %s (%d-bit) CAN ID 0x%0*x, "
661 		    "RTR %d, CAN-FD %d, BRS %d, DLC %d", frame_no,
662 		    (frame.flags & CAN_FRAME_IDE) != 0 ? "extended" : "standard",
663 		    (frame.flags & CAN_FRAME_IDE) != 0 ? 29 : 11,
664 		    (frame.flags & CAN_FRAME_IDE) != 0 ? 8 : 3, frame.id,
665 		    (frame.flags & CAN_FRAME_RTR) != 0 ? 1 : 0,
666 		    (frame.flags & CAN_FRAME_FDF) != 0 ? 1 : 0,
667 		    (frame.flags & CAN_FRAME_BRS) != 0 ? 1 : 0,
668 		    can_dlc_to_bytes(frame.dlc));
669 
670 	err = can_send(dev, &frame, K_NO_WAIT, can_shell_tx_callback, UINT_TO_POINTER(frame_no));
671 	if (err != 0) {
672 		shell_error(sh, "failed to enqueue CAN frame #%u (err %d)", frame_no, err);
673 		return err;
674 	}
675 
676 	return 0;
677 }
678 
cmd_can_filter_add(const struct shell * sh,size_t argc,char ** argv)679 static int cmd_can_filter_add(const struct shell *sh, size_t argc, char **argv)
680 {
681 	const struct device *dev = device_get_binding(argv[1]);
682 	struct can_filter filter;
683 	uint32_t max_id;
684 	int argidx = 2;
685 	uint32_t val;
686 	char *endptr;
687 	int err;
688 
689 	if (!device_is_ready(dev)) {
690 		shell_error(sh, "device %s not ready", argv[1]);
691 		return -ENODEV;
692 	}
693 
694 	/* Defaults */
695 	max_id = CAN_MAX_STD_ID;
696 	filter.flags = CAN_FILTER_DATA;
697 
698 	/* Parse options */
699 	while (argidx < argc && strncmp(argv[argidx], "-", 1) == 0) {
700 		if (strcmp(argv[argidx], "--") == 0) {
701 			argidx++;
702 			break;
703 		} else if (strcmp(argv[argidx], "-e") == 0) {
704 			filter.flags |= CAN_FILTER_IDE;
705 			max_id = CAN_MAX_EXT_ID;
706 			argidx++;
707 		} else if (strcmp(argv[argidx], "-f") == 0) {
708 			filter.flags |= CAN_FILTER_FDF;
709 			argidx++;
710 		} else if (strcmp(argv[argidx], "-r") == 0) {
711 			filter.flags |= CAN_FILTER_RTR;
712 			argidx++;
713 		} else if (strcmp(argv[argidx], "-R") == 0) {
714 			filter.flags &= ~(CAN_FILTER_DATA);
715 			filter.flags |= CAN_FILTER_RTR;
716 			argidx++;
717 		} else {
718 			shell_error(sh, "unsupported argument %s", argv[argidx]);
719 			shell_help(sh);
720 			return SHELL_CMD_HELP_PRINTED;
721 		}
722 	}
723 
724 	/* Parse CAN ID */
725 	if (argidx >= argc) {
726 		shell_error(sh, "missing CAN ID parameter");
727 		shell_help(sh);
728 		return SHELL_CMD_HELP_PRINTED;
729 	}
730 
731 	val = (uint32_t)strtoul(argv[argidx++], &endptr, 16);
732 	if (*endptr != '\0') {
733 		shell_error(sh, "failed to parse CAN ID");
734 		return -EINVAL;
735 	}
736 
737 	if (val > max_id) {
738 		shell_error(sh, "CAN ID 0x%0*x out of range",
739 			    (filter.flags & CAN_FILTER_IDE) != 0 ? 8 : 3,
740 			    val);
741 		return -EINVAL;
742 	}
743 
744 	filter.id = val;
745 
746 	if (argidx < argc) {
747 		/* Parse CAN ID mask */
748 		val = (uint32_t)strtoul(argv[argidx++], &endptr, 16);
749 		if (*endptr != '\0') {
750 			shell_error(sh, "failed to parse CAN ID mask");
751 			return -EINVAL;
752 		}
753 
754 		if (val > max_id) {
755 			shell_error(sh, "CAN ID mask 0x%0*x out of range",
756 				    (filter.flags & CAN_FILTER_IDE) != 0 ? 8 : 3,
757 				    val);
758 			return -EINVAL;
759 		}
760 
761 	} else {
762 		val = max_id;
763 	}
764 
765 	filter.mask = val;
766 
767 	err = can_shell_rx_msgq_poll_submit(sh);
768 	if (err != 0) {
769 		return err;
770 	}
771 
772 	shell_print(sh, "adding filter with %s (%d-bit) CAN ID 0x%0*x, "
773 		    "CAN ID mask 0x%0*x, data frames %d, RTR frames %d, CAN-FD frames %d",
774 		    (filter.flags & CAN_FILTER_IDE) != 0 ? "extended" : "standard",
775 		    (filter.flags & CAN_FILTER_IDE) != 0 ? 29 : 11,
776 		    (filter.flags & CAN_FILTER_IDE) != 0 ? 8 : 3, filter.id,
777 		    (filter.flags & CAN_FILTER_IDE) != 0 ? 8 : 3, filter.mask,
778 		    (filter.flags & CAN_FILTER_DATA) != 0 ? 1 : 0,
779 		    (filter.flags & CAN_FILTER_RTR) != 0 ? 1 : 0,
780 		    (filter.flags & CAN_FILTER_FDF) != 0 ? 1 : 0);
781 
782 	err = can_add_rx_filter_msgq(dev, &can_shell_rx_msgq, &filter);
783 	if (err < 0) {
784 		shell_error(sh, "failed to add filter (err %d)", err);
785 		return err;
786 	}
787 
788 	shell_print(sh, "filter ID: %d", err);
789 
790 	return 0;
791 }
792 
cmd_can_filter_remove(const struct shell * sh,size_t argc,char ** argv)793 static int cmd_can_filter_remove(const struct shell *sh, size_t argc, char **argv)
794 {
795 	const struct device *dev = device_get_binding(argv[1]);
796 	int filter_id;
797 	char *endptr;
798 
799 	if (!device_is_ready(dev)) {
800 		shell_error(sh, "device %s not ready", argv[1]);
801 		return -ENODEV;
802 	}
803 
804 	/* Parse filter ID */
805 	filter_id = (int)strtol(argv[2], &endptr, 10);
806 	if (*endptr != '\0') {
807 		shell_error(sh, "failed to parse filter ID");
808 		return -EINVAL;
809 	}
810 
811 	shell_print(sh, "removing filter with ID %d", filter_id);
812 	can_remove_rx_filter(dev, filter_id);
813 
814 	return 0;
815 }
816 
cmd_can_recover(const struct shell * sh,size_t argc,char ** argv)817 static int cmd_can_recover(const struct shell *sh, size_t argc, char **argv)
818 {
819 	const struct device *dev = device_get_binding(argv[1]);
820 	k_timeout_t timeout = K_FOREVER;
821 	int millisec;
822 	char *endptr;
823 	int err;
824 
825 	if (!device_is_ready(dev)) {
826 		shell_error(sh, "device %s not ready", argv[1]);
827 		return -ENODEV;
828 	}
829 
830 	if (argc >= 3) {
831 		/* Parse timeout */
832 		millisec = (int)strtol(argv[2], &endptr, 10);
833 		if (*endptr != '\0') {
834 			shell_error(sh, "failed to parse timeout");
835 			return -EINVAL;
836 		}
837 
838 		timeout = K_MSEC(millisec);
839 		shell_print(sh, "recovering, timeout %d ms", millisec);
840 	} else {
841 		shell_print(sh, "recovering, no timeout");
842 	}
843 
844 	err = can_recover(dev, timeout);
845 	if (err != 0) {
846 		shell_error(sh, "failed to recover CAN controller from bus-off (err %d)", err);
847 		return err;
848 	}
849 
850 	return 0;
851 }
852 
cmd_can_device_name(size_t idx,struct shell_static_entry * entry)853 static void cmd_can_device_name(size_t idx, struct shell_static_entry *entry)
854 {
855 	const struct device *dev = shell_device_lookup(idx, NULL);
856 
857 	entry->syntax = (dev != NULL) ? dev->name : NULL;
858 	entry->handler = NULL;
859 	entry->help = NULL;
860 	entry->subcmd = NULL;
861 }
862 
863 SHELL_DYNAMIC_CMD_CREATE(dsub_can_device_name, cmd_can_device_name);
864 
865 static void cmd_can_mode(size_t idx, struct shell_static_entry *entry);
866 
867 SHELL_DYNAMIC_CMD_CREATE(dsub_can_mode, cmd_can_mode);
868 
cmd_can_mode(size_t idx,struct shell_static_entry * entry)869 static void cmd_can_mode(size_t idx, struct shell_static_entry *entry)
870 {
871 	if (idx < ARRAY_SIZE(can_shell_mode_map)) {
872 		entry->syntax = can_shell_mode_map[idx].name;
873 
874 	} else {
875 		entry->syntax = NULL;
876 	}
877 
878 	entry->handler = NULL;
879 	entry->help = NULL;
880 	entry->subcmd = &dsub_can_mode;
881 }
882 
cmd_can_device_name_mode(size_t idx,struct shell_static_entry * entry)883 static void cmd_can_device_name_mode(size_t idx, struct shell_static_entry *entry)
884 {
885 	const struct device *dev = shell_device_lookup(idx, NULL);
886 
887 	entry->syntax = (dev != NULL) ? dev->name : NULL;
888 	entry->handler = NULL;
889 	entry->help = NULL;
890 	entry->subcmd = &dsub_can_mode;
891 }
892 
893 SHELL_DYNAMIC_CMD_CREATE(dsub_can_device_name_mode, cmd_can_device_name_mode);
894 
895 SHELL_STATIC_SUBCMD_SET_CREATE(sub_can_filter_cmds,
896 	SHELL_CMD_ARG(add, &dsub_can_device_name,
897 		"Add rx filter\n"
898 		"Usage: can filter add <device> [-e] [-f] [-r] [-R] <CAN ID> [CAN ID mask]\n"
899 		"-e  use extended (29-bit) CAN ID/CAN ID mask\n"
900 		"-f  match CAN-FD format frames\n"
901 		"-r  also match Remote Transmission Request (RTR) frames\n"
902 		"-R  only match Remote Transmission Request (RTR) frames",
903 		cmd_can_filter_add, 3, 5),
904 	SHELL_CMD_ARG(remove, &dsub_can_device_name,
905 		"Remove rx filter\n"
906 		"Usage: can filter remove <device> <filter_id>",
907 		cmd_can_filter_remove, 3, 0),
908 	SHELL_SUBCMD_SET_END
909 );
910 
911 SHELL_STATIC_SUBCMD_SET_CREATE(sub_can_cmds,
912 	SHELL_CMD_ARG(start, &dsub_can_device_name,
913 		"Start CAN controller\n"
914 		"Usage: can start <device>",
915 		cmd_can_start, 2, 0),
916 	SHELL_CMD_ARG(stop, &dsub_can_device_name,
917 		"Stop CAN controller\n"
918 		"Usage: can stop <device>",
919 		cmd_can_stop, 2, 0),
920 	SHELL_CMD_ARG(show, &dsub_can_device_name,
921 		"Show CAN controller information\n"
922 		"Usage: can show <device>",
923 		cmd_can_show, 2, 0),
924 	SHELL_CMD_ARG(bitrate, &dsub_can_device_name,
925 		"Set CAN controller bitrate (sample point and SJW optional)\n"
926 		"Usage: can bitrate <device> <bitrate> [sample point] [sjw]",
927 		cmd_can_bitrate_set, 3, 2),
928 	SHELL_COND_CMD_ARG(CONFIG_CAN_FD_MODE,
929 		dbitrate, &dsub_can_device_name,
930 		"Set CAN controller data phase bitrate (sample point and SJW optional)\n"
931 		"Usage: can dbitrate <device> <data phase bitrate> [sample point] [sjw]",
932 		cmd_can_dbitrate_set, 3, 2),
933 	SHELL_CMD_ARG(mode, &dsub_can_device_name_mode,
934 		"Set CAN controller mode\n"
935 		"Usage: can mode <device> <mode> [mode] [mode] [...]",
936 		cmd_can_mode_set, 3, SHELL_OPT_ARG_CHECK_SKIP),
937 	SHELL_CMD_ARG(send, &dsub_can_device_name,
938 		"Enqueue a CAN frame for sending\n"
939 		"Usage: can send <device> [-e] [-r] [-f] [-b] <CAN ID> [data] [...]\n"
940 		"-e  use extended (29-bit) CAN ID\n"
941 		"-r  send Remote Transmission Request (RTR) frame\n"
942 		"-f  use CAN-FD frame format\n"
943 		"-b  use CAN-FD Bit Rate Switching (BRS)",
944 		cmd_can_send, 3, SHELL_OPT_ARG_CHECK_SKIP),
945 	SHELL_CMD(filter, &sub_can_filter_cmds,
946 		"CAN rx filter commands\n"
947 		"Usage: can filter <add|remove> <device> ...",
948 		NULL),
949 	SHELL_EXPR_CMD_ARG(!IS_ENABLED(CONFIG_CAN_AUTO_BUS_OFF_RECOVERY),
950 		recover, &dsub_can_device_name,
951 		"Recover CAN controller from bus-off state\n"
952 		"Usage: can recover <device> [timeout ms]",
953 		cmd_can_recover, 2, 1),
954 	SHELL_SUBCMD_SET_END
955 );
956 
957 SHELL_CMD_REGISTER(can, &sub_can_cmds, "CAN controller commands", NULL);
958