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