1 /*
2 * SPDX-FileCopyrightText: Copyright (c) 2024 Fabian Blatz <fabianblatz@gmail.com>
3 * SPDX-License-Identifier: Apache-2.0
4 */
5
6 #include <zephyr/device.h>
7 #include <zephyr/drivers/stepper.h>
8 #include <zephyr/drivers/stepper/stepper_fake.h>
9 #include <zephyr/fff.h>
10
11 #ifdef CONFIG_ZTEST
12 #include <zephyr/ztest.h>
13 #endif /* CONFIG_ZTEST */
14
15 struct fake_stepper_drv_data {
16 enum stepper_drv_micro_step_resolution micro_step_res;
17 };
18
19 struct fake_stepper_data {
20 int32_t actual_position;
21 };
22
23 DEFINE_FAKE_VALUE_FUNC(int, fake_stepper_drv_enable, const struct device *);
24
25 DEFINE_FAKE_VALUE_FUNC(int, fake_stepper_drv_disable, const struct device *);
26
27 DEFINE_FAKE_VALUE_FUNC(int, fake_stepper_drv_set_micro_step_res, const struct device *,
28 enum stepper_drv_micro_step_resolution);
29
30 DEFINE_FAKE_VALUE_FUNC(int, fake_stepper_drv_get_micro_step_res, const struct device *,
31 enum stepper_drv_micro_step_resolution *);
32
33 DEFINE_FAKE_VALUE_FUNC(int, fake_stepper_drv_set_event_cb, const struct device *,
34 stepper_drv_event_cb_t, void *);
35
36 DEFINE_FAKE_VALUE_FUNC(int, fake_stepper_is_moving, const struct device *, bool *);
37
38 DEFINE_FAKE_VALUE_FUNC(int, fake_stepper_move_by, const struct device *, int32_t);
39
40 DEFINE_FAKE_VALUE_FUNC(int, fake_stepper_set_microstep_interval, const struct device *, uint64_t);
41
42 DEFINE_FAKE_VALUE_FUNC(int, fake_stepper_set_reference_position, const struct device *, int32_t);
43
44 DEFINE_FAKE_VALUE_FUNC(int, fake_stepper_get_actual_position, const struct device *, int32_t *);
45
46 DEFINE_FAKE_VALUE_FUNC(int, fake_stepper_move_to, const struct device *, int32_t);
47
48 DEFINE_FAKE_VALUE_FUNC(int, fake_stepper_run, const struct device *, enum stepper_direction);
49
50 DEFINE_FAKE_VALUE_FUNC(int, fake_stepper_stop, const struct device *);
51
52 DEFINE_FAKE_VALUE_FUNC(int, fake_stepper_set_event_callback, const struct device *,
53 stepper_event_callback_t, void *);
54
55 static int
fake_stepper_drv_set_micro_step_res_delegate(const struct device * dev,const enum stepper_drv_micro_step_resolution res)56 fake_stepper_drv_set_micro_step_res_delegate(const struct device *dev,
57 const enum stepper_drv_micro_step_resolution res)
58 {
59 struct fake_stepper_drv_data *data = dev->data;
60
61 data->micro_step_res = res;
62
63 return 0;
64 }
65
fake_stepper_drv_get_micro_step_res_delegate(const struct device * dev,enum stepper_drv_micro_step_resolution * res)66 static int fake_stepper_drv_get_micro_step_res_delegate(const struct device *dev,
67 enum stepper_drv_micro_step_resolution *res)
68 {
69 struct fake_stepper_drv_data *data = dev->data;
70
71 *res = data->micro_step_res;
72
73 return 0;
74 }
75
fake_stepper_set_reference_position_delegate(const struct device * dev,const int32_t pos)76 static int fake_stepper_set_reference_position_delegate(const struct device *dev, const int32_t pos)
77 {
78 struct fake_stepper_data *data = dev->data;
79
80 data->actual_position = pos;
81
82 return 0;
83 }
84
fake_stepper_get_actual_position_delegate(const struct device * dev,int32_t * pos)85 static int fake_stepper_get_actual_position_delegate(const struct device *dev, int32_t *pos)
86 {
87 struct fake_stepper_data *data = dev->data;
88
89 *pos = data->actual_position;
90
91 return 0;
92 }
93
94 #ifdef CONFIG_ZTEST
fake_stepper_reset_rule_before(const struct ztest_unit_test * test,void * fixture)95 static void fake_stepper_reset_rule_before(const struct ztest_unit_test *test, void *fixture)
96 {
97 ARG_UNUSED(test);
98 ARG_UNUSED(fixture);
99
100 RESET_FAKE(fake_stepper_drv_enable);
101 RESET_FAKE(fake_stepper_drv_disable);
102 RESET_FAKE(fake_stepper_drv_set_micro_step_res);
103 RESET_FAKE(fake_stepper_drv_get_micro_step_res);
104 RESET_FAKE(fake_stepper_drv_set_event_cb);
105 RESET_FAKE(fake_stepper_move_by);
106 RESET_FAKE(fake_stepper_is_moving);
107 RESET_FAKE(fake_stepper_set_microstep_interval);
108 RESET_FAKE(fake_stepper_set_reference_position);
109 RESET_FAKE(fake_stepper_get_actual_position);
110 RESET_FAKE(fake_stepper_move_to);
111 RESET_FAKE(fake_stepper_run);
112 RESET_FAKE(fake_stepper_stop);
113
114 /* Install custom fakes for the setter and getter functions */
115 fake_stepper_drv_set_micro_step_res_fake.custom_fake =
116 fake_stepper_drv_set_micro_step_res_delegate;
117 fake_stepper_drv_get_micro_step_res_fake.custom_fake =
118 fake_stepper_drv_get_micro_step_res_delegate;
119 fake_stepper_set_reference_position_fake.custom_fake =
120 fake_stepper_set_reference_position_delegate;
121 fake_stepper_get_actual_position_fake.custom_fake =
122 fake_stepper_get_actual_position_delegate;
123 }
124
125 ZTEST_RULE(fake_stepper_reset_rule, fake_stepper_reset_rule_before, NULL);
126 #endif /* CONFIG_ZTEST */
127
fake_stepper_driver_init(const struct device * dev)128 static int fake_stepper_driver_init(const struct device *dev)
129 {
130 fake_stepper_drv_set_micro_step_res_fake.custom_fake =
131 fake_stepper_drv_set_micro_step_res_delegate;
132 fake_stepper_drv_get_micro_step_res_fake.custom_fake =
133 fake_stepper_drv_get_micro_step_res_delegate;
134
135 return 0;
136 }
137
fake_stepper_init(const struct device * dev)138 static int fake_stepper_init(const struct device *dev)
139 {
140 fake_stepper_set_reference_position_fake.custom_fake =
141 fake_stepper_set_reference_position_delegate;
142 fake_stepper_get_actual_position_fake.custom_fake =
143 fake_stepper_get_actual_position_delegate;
144
145 return 0;
146 }
147
148 static DEVICE_API(stepper_drv, fake_stepper_drv_api) = {
149 .enable = fake_stepper_drv_enable,
150 .disable = fake_stepper_drv_disable,
151 .set_micro_step_res = fake_stepper_drv_set_micro_step_res,
152 .get_micro_step_res = fake_stepper_drv_get_micro_step_res,
153 .set_event_cb = fake_stepper_drv_set_event_cb,
154 };
155
156 static DEVICE_API(stepper, fake_stepper_api) = {
157 .move_by = fake_stepper_move_by,
158 .is_moving = fake_stepper_is_moving,
159 .set_microstep_interval = fake_stepper_set_microstep_interval,
160 .set_reference_position = fake_stepper_set_reference_position,
161 .get_actual_position = fake_stepper_get_actual_position,
162 .move_to = fake_stepper_move_to,
163 .run = fake_stepper_run,
164 .stop = fake_stepper_stop,
165 .set_event_callback = fake_stepper_set_event_callback,
166 };
167
168 #define FAKE_STEPPER_DRV_INIT(inst) \
169 \
170 static struct fake_stepper_drv_data fake_stepper_drv_data_##inst; \
171 \
172 DEVICE_DT_INST_DEFINE(inst, fake_stepper_driver_init, NULL, \
173 &fake_stepper_drv_data_##inst, NULL, POST_KERNEL, \
174 CONFIG_STEPPER_INIT_PRIORITY, &fake_stepper_drv_api);
175
176 #define FAKE_STEPPER_INIT(inst) \
177 \
178 static struct fake_stepper_data fake_stepper_data_##inst; \
179 \
180 DEVICE_DT_INST_DEFINE(inst, fake_stepper_init, NULL, \
181 &fake_stepper_data_##inst, NULL, POST_KERNEL, \
182 CONFIG_STEPPER_INIT_PRIORITY, &fake_stepper_api);
183
184 #define DT_DRV_COMPAT zephyr_fake_stepper_drv
185 DT_INST_FOREACH_STATUS_OKAY(FAKE_STEPPER_DRV_INIT)
186 #undef DT_DRV_COMPAT
187
188 #define DT_DRV_COMPAT zephyr_fake_stepper
189 DT_INST_FOREACH_STATUS_OKAY(FAKE_STEPPER_INIT)
190 #undef DT_DRV_COMPAT
191