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 #define DT_DRV_COMPAT zephyr_fake_stepper
16 
17 struct fake_stepper_data {
18 	enum stepper_micro_step_resolution micro_step_res;
19 	int32_t actual_position;
20 };
21 
22 DEFINE_FAKE_VALUE_FUNC(int, fake_stepper_enable, const struct device *);
23 
24 DEFINE_FAKE_VALUE_FUNC(int, fake_stepper_disable, const struct device *);
25 
26 DEFINE_FAKE_VALUE_FUNC(int, fake_stepper_is_moving, const struct device *, bool *);
27 
28 DEFINE_FAKE_VALUE_FUNC(int, fake_stepper_move_by, const struct device *, int32_t);
29 
30 DEFINE_FAKE_VALUE_FUNC(int, fake_stepper_set_microstep_interval, const struct device *, uint64_t);
31 
32 DEFINE_FAKE_VALUE_FUNC(int, fake_stepper_set_micro_step_res, const struct device *,
33 		       enum stepper_micro_step_resolution);
34 
35 DEFINE_FAKE_VALUE_FUNC(int, fake_stepper_get_micro_step_res, const struct device *,
36 		       enum stepper_micro_step_resolution *);
37 
38 DEFINE_FAKE_VALUE_FUNC(int, fake_stepper_set_reference_position, const struct device *, int32_t);
39 
40 DEFINE_FAKE_VALUE_FUNC(int, fake_stepper_get_actual_position, const struct device *, int32_t *);
41 
42 DEFINE_FAKE_VALUE_FUNC(int, fake_stepper_move_to, const struct device *, int32_t);
43 
44 DEFINE_FAKE_VALUE_FUNC(int, fake_stepper_run, const struct device *, enum stepper_direction);
45 
46 DEFINE_FAKE_VALUE_FUNC(int, fake_stepper_stop, const struct device *);
47 
48 DEFINE_FAKE_VALUE_FUNC(int, fake_stepper_set_event_callback, const struct device *,
49 		       stepper_event_callback_t, void *);
50 
fake_stepper_set_micro_step_res_delegate(const struct device * dev,const enum stepper_micro_step_resolution res)51 static int fake_stepper_set_micro_step_res_delegate(const struct device *dev,
52 						    const enum stepper_micro_step_resolution res)
53 {
54 	struct fake_stepper_data *data = dev->data;
55 
56 	data->micro_step_res = res;
57 
58 	return 0;
59 }
60 
fake_stepper_get_micro_step_res_delegate(const struct device * dev,enum stepper_micro_step_resolution * res)61 static int fake_stepper_get_micro_step_res_delegate(const struct device *dev,
62 						    enum stepper_micro_step_resolution *res)
63 {
64 	struct fake_stepper_data *data = dev->data;
65 
66 	*res = data->micro_step_res;
67 
68 	return 0;
69 }
70 
fake_stepper_set_reference_position_delegate(const struct device * dev,const int32_t pos)71 static int fake_stepper_set_reference_position_delegate(const struct device *dev, const int32_t pos)
72 {
73 	struct fake_stepper_data *data = dev->data;
74 
75 	data->actual_position = pos;
76 
77 	return 0;
78 }
79 
fake_stepper_get_actual_position_delegate(const struct device * dev,int32_t * pos)80 static int fake_stepper_get_actual_position_delegate(const struct device *dev, int32_t *pos)
81 {
82 	struct fake_stepper_data *data = dev->data;
83 
84 	*pos = data->actual_position;
85 
86 	return 0;
87 }
88 
89 #ifdef CONFIG_ZTEST
fake_stepper_reset_rule_before(const struct ztest_unit_test * test,void * fixture)90 static void fake_stepper_reset_rule_before(const struct ztest_unit_test *test, void *fixture)
91 {
92 	ARG_UNUSED(test);
93 	ARG_UNUSED(fixture);
94 
95 	RESET_FAKE(fake_stepper_enable);
96 	RESET_FAKE(fake_stepper_disable);
97 	RESET_FAKE(fake_stepper_move_by);
98 	RESET_FAKE(fake_stepper_is_moving);
99 	RESET_FAKE(fake_stepper_set_microstep_interval);
100 	RESET_FAKE(fake_stepper_set_micro_step_res);
101 	RESET_FAKE(fake_stepper_get_micro_step_res);
102 	RESET_FAKE(fake_stepper_set_reference_position);
103 	RESET_FAKE(fake_stepper_get_actual_position);
104 	RESET_FAKE(fake_stepper_move_to);
105 	RESET_FAKE(fake_stepper_run);
106 	RESET_FAKE(fake_stepper_stop);
107 
108 	/* Install custom fakes for the setter and getter functions */
109 	fake_stepper_set_micro_step_res_fake.custom_fake = fake_stepper_set_micro_step_res_delegate;
110 	fake_stepper_get_micro_step_res_fake.custom_fake = fake_stepper_get_micro_step_res_delegate;
111 	fake_stepper_set_reference_position_fake.custom_fake =
112 		fake_stepper_set_reference_position_delegate;
113 	fake_stepper_get_actual_position_fake.custom_fake =
114 		fake_stepper_get_actual_position_delegate;
115 }
116 
117 ZTEST_RULE(fake_stepper_reset_rule, fake_stepper_reset_rule_before, NULL);
118 #endif /* CONFIG_ZTEST */
119 
fake_stepper_init(const struct device * dev)120 static int fake_stepper_init(const struct device *dev)
121 {
122 	fake_stepper_set_micro_step_res_fake.custom_fake = fake_stepper_set_micro_step_res_delegate;
123 	fake_stepper_get_micro_step_res_fake.custom_fake = fake_stepper_get_micro_step_res_delegate;
124 	fake_stepper_set_reference_position_fake.custom_fake =
125 		fake_stepper_set_reference_position_delegate;
126 	fake_stepper_get_actual_position_fake.custom_fake =
127 		fake_stepper_get_actual_position_delegate;
128 
129 	return 0;
130 }
131 
132 static DEVICE_API(stepper, fake_stepper_driver_api) = {
133 	.enable = fake_stepper_enable,
134 	.disable = fake_stepper_disable,
135 	.move_by = fake_stepper_move_by,
136 	.is_moving = fake_stepper_is_moving,
137 	.set_microstep_interval = fake_stepper_set_microstep_interval,
138 	.set_micro_step_res = fake_stepper_set_micro_step_res,
139 	.get_micro_step_res = fake_stepper_get_micro_step_res,
140 	.set_reference_position = fake_stepper_set_reference_position,
141 	.get_actual_position = fake_stepper_get_actual_position,
142 	.move_to = fake_stepper_move_to,
143 	.run = fake_stepper_run,
144 	.stop = fake_stepper_stop,
145 	.set_event_callback = fake_stepper_set_event_callback,
146 };
147 
148 #define FAKE_STEPPER_INIT(inst)                                                                    \
149                                                                                                    \
150 	static struct fake_stepper_data fake_stepper_data_##inst;                                  \
151                                                                                                    \
152 	DEVICE_DT_INST_DEFINE(inst, fake_stepper_init, NULL, &fake_stepper_data_##inst, NULL,      \
153 			      POST_KERNEL, CONFIG_STEPPER_INIT_PRIORITY,                           \
154 			      &fake_stepper_driver_api);
155 
156 DT_INST_FOREACH_STATUS_OKAY(FAKE_STEPPER_INIT)
157