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