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 
12 #ifdef CONFIG_ZTEST_NEW_API
13 #include <zephyr/ztest.h>
14 #endif /* CONFIG_ZTEST_NEW_API */
15 
16 #define DT_DRV_COMPAT zephyr_fake_can
17 
18 DEFINE_FAKE_VALUE_FUNC(int, fake_can_start, const struct device *);
19 
20 DEFINE_FAKE_VALUE_FUNC(int, fake_can_stop, const struct device *);
21 
22 DEFINE_FAKE_VALUE_FUNC(int, fake_can_set_timing, const struct device *, const struct can_timing *);
23 
24 DEFINE_FAKE_VALUE_FUNC(int, fake_can_set_timing_data, const struct device *,
25 		       const struct can_timing *);
26 
27 DEFINE_FAKE_VALUE_FUNC(int, fake_can_get_capabilities, const struct device *, can_mode_t *);
28 
29 DEFINE_FAKE_VALUE_FUNC(int, fake_can_set_mode, const struct device *, can_mode_t);
30 
31 DEFINE_FAKE_VALUE_FUNC(int, fake_can_send, const struct device *, const struct can_frame *,
32 		       k_timeout_t, can_tx_callback_t, void *);
33 
34 DEFINE_FAKE_VALUE_FUNC(int, fake_can_add_rx_filter, const struct device *, can_rx_callback_t,
35 		       void *, const struct can_filter *);
36 
37 DEFINE_FAKE_VOID_FUNC(fake_can_remove_rx_filter, const struct device *, int);
38 
39 DEFINE_FAKE_VALUE_FUNC(int, fake_can_recover, const struct device *, k_timeout_t);
40 
41 DEFINE_FAKE_VALUE_FUNC(int, fake_can_get_state, const struct device *, enum can_state *,
42 		       struct can_bus_err_cnt *);
43 
44 DEFINE_FAKE_VOID_FUNC(fake_can_set_state_change_callback, const struct device *,
45 		      can_state_change_callback_t, void *);
46 
47 DEFINE_FAKE_VALUE_FUNC(int, fake_can_get_max_filters, const struct device *, bool);
48 
49 #ifdef CONFIG_ZTEST_NEW_API
fake_can_reset_rule_before(const struct ztest_unit_test * test,void * fixture)50 static void fake_can_reset_rule_before(const struct ztest_unit_test *test, void *fixture)
51 {
52 	ARG_UNUSED(test);
53 	ARG_UNUSED(fixture);
54 
55 	RESET_FAKE(fake_can_start);
56 	RESET_FAKE(fake_can_stop);
57 	RESET_FAKE(fake_can_get_capabilities);
58 	RESET_FAKE(fake_can_set_mode);
59 	RESET_FAKE(fake_can_set_timing);
60 	RESET_FAKE(fake_can_set_timing_data);
61 	RESET_FAKE(fake_can_send);
62 	RESET_FAKE(fake_can_add_rx_filter);
63 	RESET_FAKE(fake_can_remove_rx_filter);
64 	RESET_FAKE(fake_can_get_state);
65 	RESET_FAKE(fake_can_recover);
66 	RESET_FAKE(fake_can_set_state_change_callback);
67 	RESET_FAKE(fake_can_get_max_filters);
68 }
69 
70 ZTEST_RULE(fake_can_reset_rule, fake_can_reset_rule_before, NULL);
71 #endif /* CONFIG_ZTEST_NEW_API */
72 
fake_can_get_core_clock(const struct device * dev,uint32_t * rate)73 static int fake_can_get_core_clock(const struct device *dev, uint32_t *rate)
74 {
75 	ARG_UNUSED(dev);
76 
77 	*rate = 16000000;
78 
79 	return 0;
80 }
81 
fake_can_get_max_bitrate(const struct device * dev,uint32_t * max_bitrate)82 static int fake_can_get_max_bitrate(const struct device *dev, uint32_t *max_bitrate)
83 {
84 	ARG_UNUSED(dev);
85 
86 	*max_bitrate = 5000000;
87 
88 	return 0;
89 }
90 
91 static const struct can_driver_api fake_can_driver_api = {
92 	.start = fake_can_start,
93 	.stop = fake_can_stop,
94 	.get_capabilities = fake_can_get_capabilities,
95 	.set_mode = fake_can_set_mode,
96 	.set_timing = fake_can_set_timing,
97 	.send = fake_can_send,
98 	.add_rx_filter = fake_can_add_rx_filter,
99 	.remove_rx_filter = fake_can_remove_rx_filter,
100 	.get_state = fake_can_get_state,
101 #ifndef CONFIG_CAN_AUTO_BUS_OFF_RECOVERY
102 	.recover = fake_can_recover,
103 #endif /* CONFIG_CAN_AUTO_BUS_OFF_RECOVERY */
104 	.set_state_change_callback = fake_can_set_state_change_callback,
105 	.get_core_clock = fake_can_get_core_clock,
106 	.get_max_filters = fake_can_get_max_filters,
107 	.get_max_bitrate = fake_can_get_max_bitrate,
108 	.timing_min = {
109 		.sjw = 0x01,
110 		.prop_seg = 0x01,
111 		.phase_seg1 = 0x01,
112 		.phase_seg2 = 0x01,
113 		.prescaler = 0x01
114 	},
115 	.timing_max = {
116 		.sjw = 0x0f,
117 		.prop_seg = 0x0f,
118 		.phase_seg1 = 0x0f,
119 		.phase_seg2 = 0x0f,
120 		.prescaler = 0xffff
121 	},
122 #ifdef CONFIG_CAN_FD_MODE
123 	.set_timing_data = fake_can_set_timing_data,
124 	.timing_data_min = {
125 		.sjw = 0x01,
126 		.prop_seg = 0x01,
127 		.phase_seg1 = 0x01,
128 		.phase_seg2 = 0x01,
129 		.prescaler = 0x01
130 	},
131 	.timing_data_max = {
132 		.sjw = 0x0f,
133 		.prop_seg = 0x0f,
134 		.phase_seg1 = 0x0f,
135 		.phase_seg2 = 0x0f,
136 		.prescaler = 0xffff
137 	},
138 #endif /* CONFIG_CAN_FD_MODE */
139 };
140 
141 #define FAKE_CAN_INIT(inst)						     \
142 	CAN_DEVICE_DT_INST_DEFINE(inst, NULL, NULL, NULL, NULL, POST_KERNEL, \
143 				  CONFIG_CAN_INIT_PRIORITY,                  \
144 				  &fake_can_driver_api);
145 
146 DT_INST_FOREACH_STATUS_OKAY(FAKE_CAN_INIT)
147