1 /*
2  * Copyright (c) 2022 Vestas Wind Systems A/S
3  *
4  * SPDX-License-Identifier: Apache-2.0
5  */
6 
7 #include <zephyr/device.h>
8 #include <zephyr/drivers/can.h>
9 #include <zephyr/drivers/can/can_fake.h>
10 #include <zephyr/fff.h>
11 #include <zephyr/sys/util.h>
12 
13 #ifdef CONFIG_ZTEST
14 #include <zephyr/ztest.h>
15 #endif /* CONFIG_ZTEST */
16 
17 #define DT_DRV_COMPAT zephyr_fake_can
18 
19 struct fake_can_config {
20 	const struct can_driver_config common;
21 };
22 
23 struct fake_can_data {
24 	struct can_driver_data common;
25 };
26 
27 DEFINE_FAKE_VALUE_FUNC(int, fake_can_start, const struct device *);
28 
29 DEFINE_FAKE_VALUE_FUNC(int, fake_can_stop, const struct device *);
30 
31 DEFINE_FAKE_VALUE_FUNC(int, fake_can_set_timing, const struct device *, const struct can_timing *);
32 
33 DEFINE_FAKE_VALUE_FUNC(int, fake_can_set_timing_data, const struct device *,
34 		       const struct can_timing *);
35 
36 DEFINE_FAKE_VALUE_FUNC(int, fake_can_get_capabilities, const struct device *, can_mode_t *);
37 
38 DEFINE_FAKE_VALUE_FUNC(int, fake_can_set_mode, const struct device *, can_mode_t);
39 
40 DEFINE_FAKE_VALUE_FUNC(int, fake_can_send, const struct device *, const struct can_frame *,
41 		       k_timeout_t, can_tx_callback_t, void *);
42 
43 DEFINE_FAKE_VALUE_FUNC(int, fake_can_add_rx_filter, const struct device *, can_rx_callback_t,
44 		       void *, const struct can_filter *);
45 
46 DEFINE_FAKE_VOID_FUNC(fake_can_remove_rx_filter, const struct device *, int);
47 
48 DEFINE_FAKE_VALUE_FUNC(int, fake_can_recover, const struct device *, k_timeout_t);
49 
50 DEFINE_FAKE_VALUE_FUNC(int, fake_can_get_state, const struct device *, enum can_state *,
51 		       struct can_bus_err_cnt *);
52 
53 DEFINE_FAKE_VOID_FUNC(fake_can_set_state_change_callback, const struct device *,
54 		      can_state_change_callback_t, void *);
55 
56 DEFINE_FAKE_VALUE_FUNC(int, fake_can_get_max_filters, const struct device *, bool);
57 
58 DEFINE_FAKE_VALUE_FUNC(int, fake_can_get_core_clock, const struct device *, uint32_t *);
59 
fake_can_get_core_clock_delegate(const struct device * dev,uint32_t * rate)60 static int fake_can_get_core_clock_delegate(const struct device *dev, uint32_t *rate)
61 {
62 	ARG_UNUSED(dev);
63 
64 	/* Recommended CAN clock from CiA 601-3 */
65 	*rate = MHZ(80);
66 
67 	return 0;
68 }
69 
70 #ifdef CONFIG_ZTEST
fake_can_reset_rule_before(const struct ztest_unit_test * test,void * fixture)71 static void fake_can_reset_rule_before(const struct ztest_unit_test *test, void *fixture)
72 {
73 	ARG_UNUSED(test);
74 	ARG_UNUSED(fixture);
75 
76 	RESET_FAKE(fake_can_start);
77 	RESET_FAKE(fake_can_stop);
78 	RESET_FAKE(fake_can_get_capabilities);
79 	RESET_FAKE(fake_can_set_mode);
80 	RESET_FAKE(fake_can_set_timing);
81 	RESET_FAKE(fake_can_set_timing_data);
82 	RESET_FAKE(fake_can_send);
83 	RESET_FAKE(fake_can_add_rx_filter);
84 	RESET_FAKE(fake_can_remove_rx_filter);
85 	RESET_FAKE(fake_can_get_state);
86 	RESET_FAKE(fake_can_recover);
87 	RESET_FAKE(fake_can_set_state_change_callback);
88 	RESET_FAKE(fake_can_get_max_filters);
89 	RESET_FAKE(fake_can_get_core_clock);
90 
91 	/* Re-install default delegate for reporting the core clock */
92 	fake_can_get_core_clock_fake.custom_fake = fake_can_get_core_clock_delegate;
93 }
94 
95 ZTEST_RULE(fake_can_reset_rule, fake_can_reset_rule_before, NULL);
96 #endif /* CONFIG_ZTEST */
97 
fake_can_init(const struct device * dev)98 static int fake_can_init(const struct device *dev)
99 {
100 	/* Install default delegate for reporting the core clock */
101 	fake_can_get_core_clock_fake.custom_fake = fake_can_get_core_clock_delegate;
102 
103 	return 0;
104 }
105 
106 static DEVICE_API(can, fake_can_driver_api) = {
107 	.start = fake_can_start,
108 	.stop = fake_can_stop,
109 	.get_capabilities = fake_can_get_capabilities,
110 	.set_mode = fake_can_set_mode,
111 	.set_timing = fake_can_set_timing,
112 	.send = fake_can_send,
113 	.add_rx_filter = fake_can_add_rx_filter,
114 	.remove_rx_filter = fake_can_remove_rx_filter,
115 	.get_state = fake_can_get_state,
116 #ifdef CONFIG_CAN_MANUAL_RECOVERY_MODE
117 	.recover = fake_can_recover,
118 #endif /* CONFIG_CAN_MANUAL_RECOVERY_MODE */
119 	.set_state_change_callback = fake_can_set_state_change_callback,
120 	.get_core_clock = fake_can_get_core_clock,
121 	.get_max_filters = fake_can_get_max_filters,
122 	/* Recommended configuration ranges from CiA 601-2 */
123 	.timing_min = {
124 		.sjw = 1,
125 		.prop_seg = 0,
126 		.phase_seg1 = 2,
127 		.phase_seg2 = 2,
128 		.prescaler = 1
129 	},
130 	.timing_max = {
131 		.sjw = 128,
132 		.prop_seg = 0,
133 		.phase_seg1 = 256,
134 		.phase_seg2 = 128,
135 		.prescaler = 32
136 	},
137 #ifdef CONFIG_CAN_FD_MODE
138 	.set_timing_data = fake_can_set_timing_data,
139 	/* Recommended configuration ranges from CiA 601-2 */
140 	.timing_data_min = {
141 		.sjw = 1,
142 		.prop_seg = 0,
143 		.phase_seg1 = 1,
144 		.phase_seg2 = 1,
145 		.prescaler = 1
146 	},
147 	.timing_data_max = {
148 		.sjw = 16,
149 		.prop_seg = 0,
150 		.phase_seg1 = 32,
151 		.phase_seg2 = 16,
152 		.prescaler = 32
153 	},
154 #endif /* CONFIG_CAN_FD_MODE */
155 };
156 
157 #ifdef CONFIG_CAN_FD_MODE
158 #define FAKE_CAN_MAX_BITRATE 8000000
159 #else /* CONFIG_CAN_FD_MODE */
160 #define FAKE_CAN_MAX_BITRATE 1000000
161 #endif /* !CONFIG_CAN_FD_MODE */
162 
163 #define FAKE_CAN_INIT(inst)						                \
164 	static const struct fake_can_config fake_can_config_##inst = {	                \
165 		.common = CAN_DT_DRIVER_CONFIG_INST_GET(inst, 0, FAKE_CAN_MAX_BITRATE), \
166 	};								                \
167 									                \
168 	static struct fake_can_data fake_can_data_##inst;		                \
169 									                \
170 	CAN_DEVICE_DT_INST_DEFINE(inst, fake_can_init, NULL, &fake_can_data_##inst,     \
171 				  &fake_can_config_##inst, POST_KERNEL,	                \
172 				  CONFIG_CAN_INIT_PRIORITY,                             \
173 				  &fake_can_driver_api);
174 
175 DT_INST_FOREACH_STATUS_OKAY(FAKE_CAN_INIT)
176