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