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