-
Notifications
You must be signed in to change notification settings - Fork 7.3k
/
Copy pathstep_dir_stepper_common.h
239 lines (211 loc) · 8.45 KB
/
step_dir_stepper_common.h
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
/*
* Copyright 2024 Fabian Blatz <[email protected]>
*
* SPDX-License-Identifier: Apache-2.0
*/
#ifndef ZEPHYR_DRIVER_STEPPER_STEP_DIR_STEPPER_COMMON_H_
#define ZEPHYR_DRIVER_STEPPER_STEP_DIR_STEPPER_COMMON_H_
/**
* @brief Stepper Driver APIs
* @defgroup step_dir_stepper Stepper Driver APIs
* @ingroup io_interfaces
* @{
*/
#include <zephyr/device.h>
#include <zephyr/drivers/gpio.h>
#include <zephyr/drivers/stepper.h>
#include <zephyr/drivers/counter.h>
#include "step_dir_stepper_timing_source.h"
/**
* @brief Common step direction stepper config.
*
* This structure **must** be placed first in the driver's config structure.
*/
struct step_dir_stepper_common_config {
const struct gpio_dt_spec step_pin;
const struct gpio_dt_spec dir_pin;
const struct gpio_dt_spec *msx_pins;
bool dual_edge;
const struct stepper_timing_source_api *timing_source;
const struct device *counter;
bool invert_direction;
};
/**
* @brief Initialize common step direction stepper config from devicetree instance.
* If the counter property is set, the timing source will be set to the counter timing
* source.
*
* @param node_id The devicetree node identifier.
*/
#define STEP_DIR_STEPPER_DT_COMMON_CONFIG_INIT(node_id, msx_gpio_array) \
{ \
IF_ENABLED( DT_NODE_HAS_PROP(node_id, msx_gpios), (.msx_pins = msx_gpio_array,)) \
.step_pin = GPIO_DT_SPEC_GET(node_id, step_gpios), \
.dir_pin = GPIO_DT_SPEC_GET(node_id, dir_gpios), \
.dual_edge = DT_PROP_OR(node_id, dual_edge_step, false), \
.counter = DEVICE_DT_GET_OR_NULL(DT_PHANDLE(node_id, counter)), \
.invert_direction = DT_PROP(node_id, invert_direction), \
.timing_source = COND_CODE_1(DT_NODE_HAS_PROP(node_id, counter), \
(&step_counter_timing_source_api), \
(&step_work_timing_source_api)), \
}
/**
* @brief Initialize common step direction stepper config from devicetree instance.
* @param inst Instance.
*/
#define STEP_DIR_STEPPER_DT_INST_COMMON_CONFIG_INIT(inst, msx_gpio_array) \
STEP_DIR_STEPPER_DT_COMMON_CONFIG_INIT(DT_DRV_INST(inst), msx_gpio_array)
/**
* @brief Common step direction stepper data.
*
* This structure **must** be placed first in the driver's data structure.
*/
struct step_dir_stepper_common_data {
const struct device *dev;
struct k_spinlock lock;
enum stepper_direction direction;
enum stepper_run_mode run_mode;
int32_t actual_position;
uint64_t microstep_interval_ns;
int32_t step_count;
stepper_event_callback_t callback;
void *event_cb_user_data;
struct k_work_delayable stepper_dwork;
#ifdef CONFIG_STEP_DIR_STEPPER_COUNTER_TIMING
struct counter_top_cfg counter_top_cfg;
bool counter_running;
#endif /* CONFIG_STEP_DIR_STEPPER_COUNTER_TIMING */
#ifdef CONFIG_STEPPER_STEP_DIR_GENERATE_ISR_SAFE_EVENTS
struct k_work event_callback_work;
struct k_msgq event_msgq;
uint8_t event_msgq_buffer[CONFIG_STEPPER_STEP_DIR_EVENT_QUEUE_LEN *
sizeof(enum stepper_event)];
#endif /* CONFIG_STEPPER_STEP_DIR_GENERATE_ISR_SAFE_EVENTS */
};
/**
* @brief Initialize common step direction stepper data from devicetree instance.
*
* @param node_id The devicetree node identifier.
*/
#define STEP_DIR_STEPPER_DT_COMMON_DATA_INIT(node_id) \
{ \
.dev = DEVICE_DT_GET(node_id), \
}
/**
* @brief Initialize common step direction stepper data from devicetree instance.
* @param inst Instance.
*/
#define STEP_DIR_STEPPER_DT_INST_COMMON_DATA_INIT(inst) \
STEP_DIR_STEPPER_DT_COMMON_DATA_INIT(DT_DRV_INST(inst))
/**
* @brief Validate the offset of the common data structures.
*
* @param config Name of the config structure.
* @param data Name of the data structure.
*/
#define STEP_DIR_STEPPER_STRUCT_CHECK(config, data) \
BUILD_ASSERT(offsetof(config, common) == 0, \
"struct step_dir_stepper_common_config must be placed first"); \
BUILD_ASSERT(offsetof(data, common) == 0, \
"struct step_dir_stepper_common_data must be placed first");
/**
* @brief Common function to initialize a step direction stepper device at init time.
*
* This function must be called at the end of the device init function.
*
* @param dev Step direction stepper device instance.
*
* @retval 0 If initialized successfully.
* @retval -errno Negative errno in case of failure.
*/
int step_dir_stepper_common_init(const struct device *dev);
/**
* @brief Move the stepper motor by a given number of micro_steps.
*
* @param dev Pointer to the device structure.
* @param micro_steps Number of micro_steps to move. Can be positive or negative.
* @return 0 on success, or a negative error code on failure.
*/
int step_dir_stepper_common_move_by(const struct device *dev, const int32_t micro_steps);
/**
* @brief Set the step interval of the stepper motor.
*
* @param dev Pointer to the device structure.
* @param microstep_interval_ns The step interval in nanoseconds.
* @return 0 on success, or a negative error code on failure.
*/
int step_dir_stepper_common_set_microstep_interval(const struct device *dev,
const uint64_t microstep_interval_ns);
/**
* @brief Set the reference position of the stepper motor.
*
* @param dev Pointer to the device structure.
* @param value The reference position value to set.
* @return 0 on success, or a negative error code on failure.
*/
int step_dir_stepper_common_set_reference_position(const struct device *dev, const int32_t value);
/**
* @brief Get the actual (reference) position of the stepper motor.
*
* @param dev Pointer to the device structure.
* @param value Pointer to a variable where the position value will be stored.
* @return 0 on success, or a negative error code on failure.
*/
int step_dir_stepper_common_get_actual_position(const struct device *dev, int32_t *value);
/**
* @brief Set the absolute target position of the stepper motor.
*
* @param dev Pointer to the device structure.
* @param value The target position to set.
* @return 0 on success, or a negative error code on failure.
*/
int step_dir_stepper_common_move_to(const struct device *dev, const int32_t value);
/**
* @brief Check if the stepper motor is still moving.
*
* @param dev Pointer to the device structure.
* @param is_moving Pointer to a boolean where the movement status will be stored.
* @return 0 on success, or a negative error code on failure.
*/
int step_dir_stepper_common_is_moving(const struct device *dev, bool *is_moving);
/**
* @brief Run the stepper with a given direction and step interval.
*
* @param dev Pointer to the device structure.
* @param direction The direction of movement (positive or negative).
* @return 0 on success, or a negative error code on failure.
*/
int step_dir_stepper_common_run(const struct device *dev, const enum stepper_direction direction);
/**
* @brief Stop the stepper motor.
*
* @param dev Pointer to the device structure.
* @return 0 on success, or a negative error code on failure.
*/
int step_dir_stepper_common_stop(const struct device *dev);
/**
* @brief Set a callback function for stepper motor events.
*
* This function sets a user-defined callback that will be invoked when a stepper motor event
* occurs.
*
* @param dev Pointer to the device structure.
* @param callback The callback function to set.
* @param user_data Pointer to user-defined data that will be passed to the callback.
* @return 0 on success, or a negative error code on failure.
*/
int step_dir_stepper_common_set_event_callback(const struct device *dev,
stepper_event_callback_t callback, void *user_data);
/**
* @brief Handle a timing signal and update the stepper position.
* @param dev Pointer to the device structure.
*/
void stepper_handle_timing_signal(const struct device *dev);
/**
* @brief Trigger callback function for stepper motor events.
* @param dev Pointer to the device structure.
* @param event The stepper_event to rigger the callback for.
*/
void stepper_trigger_callback(const struct device *dev, enum stepper_event event);
/** @} */
#endif /* ZEPHYR_DRIVER_STEPPER_STEP_DIR_STEPPER_COMMON_H_ */