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