Line data Source code
1 1 : /**
2 : * @file drivers/stepper.h
3 : *
4 : * @brief Public API for Stepper Driver
5 : *
6 : */
7 :
8 : /*
9 : * SPDX-FileCopyrightText: Copyright (c) 2024 Carl Zeiss Meditec AG
10 : * SPDX-FileCopyrightText: Copyright (c) 2024 Jilay Sandeep Pandya
11 : * SPDX-License-Identifier: Apache-2.0
12 : */
13 :
14 : #ifndef ZEPHYR_INCLUDE_DRIVERS_STEPPER_H_
15 : #define ZEPHYR_INCLUDE_DRIVERS_STEPPER_H_
16 :
17 : /**
18 : * @brief Stepper Controller Interface
19 : * @defgroup stepper_interface Stepper Controller Interface
20 : * @ingroup io_interfaces
21 : * @{
22 : */
23 :
24 : #include <zephyr/kernel.h>
25 : #include <zephyr/device.h>
26 : #include <errno.h>
27 :
28 : #ifdef __cplusplus
29 : extern "C" {
30 : #endif
31 :
32 0 : #define MICRO_STEP_RES_INDEX(res) LOG2(res)
33 :
34 : /**
35 : * @brief Stepper Motor micro step resolution options
36 : */
37 1 : enum stepper_micro_step_resolution {
38 : /** Full step resolution */
39 : STEPPER_MICRO_STEP_1 = 1,
40 : /** 2 micro steps per full step */
41 : STEPPER_MICRO_STEP_2 = 2,
42 : /** 4 micro steps per full step */
43 : STEPPER_MICRO_STEP_4 = 4,
44 : /** 8 micro steps per full step */
45 : STEPPER_MICRO_STEP_8 = 8,
46 : /** 16 micro steps per full step */
47 : STEPPER_MICRO_STEP_16 = 16,
48 : /** 32 micro steps per full step */
49 : STEPPER_MICRO_STEP_32 = 32,
50 : /** 64 micro steps per full step */
51 : STEPPER_MICRO_STEP_64 = 64,
52 : /** 128 micro steps per full step */
53 : STEPPER_MICRO_STEP_128 = 128,
54 : /** 256 micro steps per full step */
55 : STEPPER_MICRO_STEP_256 = 256,
56 : };
57 :
58 : /**
59 : * @brief Stepper Motor direction options
60 : */
61 1 : enum stepper_direction {
62 : /** Negative direction */
63 : STEPPER_DIRECTION_NEGATIVE = 0,
64 : /** Positive direction */
65 : STEPPER_DIRECTION_POSITIVE = 1,
66 : };
67 :
68 : /**
69 : * @brief Stepper Motor run mode options
70 : */
71 1 : enum stepper_run_mode {
72 : /** Hold Mode */
73 : STEPPER_RUN_MODE_HOLD = 0,
74 : /** Position Mode*/
75 : STEPPER_RUN_MODE_POSITION = 1,
76 : /** Velocity Mode */
77 : STEPPER_RUN_MODE_VELOCITY = 2,
78 : };
79 :
80 : /**
81 : * @brief Stepper Events
82 : */
83 1 : enum stepper_event {
84 : /** Steps set using move or set_target_position have been executed */
85 : STEPPER_EVENT_STEPS_COMPLETED = 0,
86 : /** Stall detected */
87 : STEPPER_EVENT_STALL_DETECTED = 1,
88 : /** Left end switch status changes to pressed */
89 : STEPPER_EVENT_LEFT_END_STOP_DETECTED = 2,
90 : /** Right end switch status changes to pressed */
91 : STEPPER_EVENT_RIGHT_END_STOP_DETECTED = 3,
92 : };
93 :
94 : /**
95 : * @cond INTERNAL_HIDDEN
96 : *
97 : * Stepper motor controller driver API definition and system call entry points.
98 : *
99 : */
100 :
101 : /**
102 : * @brief enable or disable the stepper motor controller.
103 : *
104 : * @see stepper_enable() for details.
105 : */
106 : typedef int (*stepper_enable_t)(const struct device *dev, const bool enable);
107 :
108 : /**
109 : * @brief Move the stepper motor relatively by a given number of micro_steps.
110 : *
111 : * @see stepper_move_by() for details.
112 : */
113 : typedef int (*stepper_move_by_t)(const struct device *dev, const int32_t micro_steps);
114 :
115 : /**
116 : * @brief Set the max velocity in micro_steps per seconds.
117 : *
118 : * @see stepper_set_max_velocity() for details.
119 : */
120 : typedef int (*stepper_set_max_velocity_t)(const struct device *dev,
121 : const uint32_t micro_steps_per_second);
122 :
123 : /**
124 : * @brief Set the micro-step resolution
125 : *
126 : * @see stepper_set_micro_step_res() for details.
127 : */
128 : typedef int (*stepper_set_micro_step_res_t)(const struct device *dev,
129 : const enum stepper_micro_step_resolution resolution);
130 :
131 : /**
132 : * @brief Get the micro-step resolution
133 : *
134 : * @see stepper_get_micro_step_res() for details.
135 : */
136 : typedef int (*stepper_get_micro_step_res_t)(const struct device *dev,
137 : enum stepper_micro_step_resolution *resolution);
138 : /**
139 : * @brief Set the reference position of the stepper
140 : *
141 : * @see stepper_set_actual_position() for details.
142 : */
143 : typedef int (*stepper_set_reference_position_t)(const struct device *dev, const int32_t value);
144 :
145 : /**
146 : * @brief Get the actual a.k.a reference position of the stepper
147 : *
148 : * @see stepper_get_actual_position() for details.
149 : */
150 : typedef int (*stepper_get_actual_position_t)(const struct device *dev, int32_t *value);
151 :
152 : /**
153 : * @brief Move the stepper motor absolutely by a given number of micro_steps.
154 : *
155 : * @see stepper_move_to() for details.
156 : */
157 : typedef int (*stepper_move_to_t)(const struct device *dev, const int32_t micro_steps);
158 :
159 : /**
160 : * @brief Is the target position fo the stepper reached
161 : *
162 : * @see stepper_is_moving() for details.
163 : */
164 : typedef int (*stepper_is_moving_t)(const struct device *dev, bool *is_moving);
165 :
166 : /**
167 : * @brief Run the stepper with a given velocity in a given direction
168 : *
169 : * @see stepper_run() for details.
170 : */
171 : typedef int (*stepper_run_t)(const struct device *dev, const enum stepper_direction direction,
172 : const uint32_t value);
173 :
174 : /**
175 : * @brief Callback function for stepper events
176 : */
177 : typedef void (*stepper_event_callback_t)(const struct device *dev, const enum stepper_event event,
178 : void *user_data);
179 :
180 : /**
181 : * @brief Set the callback function to be called when a stepper event occurs
182 : *
183 : * @see stepper_set_event_callback() for details.
184 : */
185 : typedef int (*stepper_set_event_callback_t)(const struct device *dev,
186 : stepper_event_callback_t callback, void *user_data);
187 :
188 : /**
189 : * @brief Stepper Motor Controller API
190 : */
191 : __subsystem struct stepper_driver_api {
192 : stepper_enable_t enable;
193 : stepper_move_by_t move_by;
194 : stepper_set_max_velocity_t set_max_velocity;
195 : stepper_set_micro_step_res_t set_micro_step_res;
196 : stepper_get_micro_step_res_t get_micro_step_res;
197 : stepper_set_reference_position_t set_reference_position;
198 : stepper_get_actual_position_t get_actual_position;
199 : stepper_move_to_t move_to;
200 : stepper_is_moving_t is_moving;
201 : stepper_run_t run;
202 : stepper_set_event_callback_t set_event_callback;
203 : };
204 :
205 : /**
206 : * @endcond
207 : */
208 :
209 : /**
210 : * @brief Enable or Disable Motor Controller
211 : *
212 : * @param dev pointer to the stepper motor controller instance
213 : * @param enable Input enable or disable motor controller
214 : *
215 : * @retval -EIO Error during Enabling
216 : * @retval 0 Success
217 : */
218 1 : __syscall int stepper_enable(const struct device *dev, const bool enable);
219 :
220 : static inline int z_impl_stepper_enable(const struct device *dev, const bool enable)
221 : {
222 : const struct stepper_driver_api *api = (const struct stepper_driver_api *)dev->api;
223 :
224 : return api->enable(dev, enable);
225 : }
226 :
227 : /**
228 : * @brief Set the micro_steps to be moved from the current position i.e. relative movement
229 : *
230 : * @details The motor will move by the given number of micro_steps from the current position.
231 : * This function is non-blocking.
232 : *
233 : * @param dev pointer to the stepper motor controller instance
234 : * @param micro_steps target micro_steps to be moved from the current position
235 : *
236 : * @retval -EIO General input / output error
237 : * @retval 0 Success
238 : */
239 1 : __syscall int stepper_move_by(const struct device *dev, int32_t micro_steps);
240 :
241 : static inline int z_impl_stepper_move_by(const struct device *dev, const int32_t micro_steps)
242 : {
243 : const struct stepper_driver_api *api = (const struct stepper_driver_api *)dev->api;
244 :
245 : return api->move_by(dev, micro_steps);
246 : }
247 :
248 : /**
249 : * @brief Set the target velocity to be reached by the motor
250 : *
251 : * @details For controllers such as DRV8825 where you
252 : * toggle the STEP Pin, the pulse_length would have to be calculated based on this parameter in the
253 : * driver. For controllers where velocity can be set, this parameter corresponds to max_velocity
254 : * @note Setting max velocity does not set the motor into motion, a combination of set_max_velocity
255 : * and move is required to set the motor into motion.
256 : *
257 : * @param dev pointer to the stepper motor controller instance
258 : * @param micro_steps_per_second speed in micro_steps per second
259 : *
260 : * @retval -EIO General input / output error
261 : * @retval -EINVAL If the requested velocity is not supported
262 : * @retval 0 Success
263 : */
264 1 : __syscall int stepper_set_max_velocity(const struct device *dev, uint32_t micro_steps_per_second);
265 :
266 : static inline int z_impl_stepper_set_max_velocity(const struct device *dev,
267 : const uint32_t micro_steps_per_second)
268 : {
269 : const struct stepper_driver_api *api = (const struct stepper_driver_api *)dev->api;
270 :
271 : return api->set_max_velocity(dev, micro_steps_per_second);
272 : }
273 :
274 : /**
275 : * @brief Set the microstep resolution in stepper motor controller
276 : *
277 : * @param dev pointer to the stepper motor controller instance
278 : * @param resolution microstep resolution
279 : *
280 : * @retval -EIO General input / output error
281 : * @retval -ENOSYS If not implemented by device driver
282 : * @retval -ENOTSUP If the requested resolution is not supported
283 : * @retval 0 Success
284 : */
285 1 : __syscall int stepper_set_micro_step_res(const struct device *dev,
286 : enum stepper_micro_step_resolution resolution);
287 :
288 : static inline int z_impl_stepper_set_micro_step_res(const struct device *dev,
289 : enum stepper_micro_step_resolution resolution)
290 : {
291 : const struct stepper_driver_api *api = (const struct stepper_driver_api *)dev->api;
292 :
293 : if (api->set_micro_step_res == NULL) {
294 : return -ENOSYS;
295 : }
296 : return api->set_micro_step_res(dev, resolution);
297 : }
298 :
299 : /**
300 : * @brief Get the microstep resolution in stepper motor controller
301 : *
302 : * @param dev pointer to the stepper motor controller instance
303 : * @param resolution microstep resolution
304 : *
305 : * @retval -EIO General input / output error
306 : * @retval -ENOSYS If not implemented by device driver
307 : * @retval 0 Success
308 : */
309 1 : __syscall int stepper_get_micro_step_res(const struct device *dev,
310 : enum stepper_micro_step_resolution *resolution);
311 :
312 : static inline int z_impl_stepper_get_micro_step_res(const struct device *dev,
313 : enum stepper_micro_step_resolution *resolution)
314 : {
315 : const struct stepper_driver_api *api = (const struct stepper_driver_api *)dev->api;
316 :
317 : if (api->get_micro_step_res == NULL) {
318 : return -ENOSYS;
319 : }
320 : return api->get_micro_step_res(dev, resolution);
321 : }
322 :
323 : /**
324 : * @brief Set the reference position of the stepper
325 : *
326 : * @param dev Pointer to the stepper motor controller instance.
327 : * @param value The reference position to set in micro-steps.
328 : *
329 : * @retval -EIO General input / output error
330 : * @retval -ENOSYS If not implemented by device driver
331 : * @retval 0 Success
332 : */
333 1 : __syscall int stepper_set_reference_position(const struct device *dev, int32_t value);
334 :
335 : static inline int z_impl_stepper_set_reference_position(const struct device *dev,
336 : const int32_t value)
337 : {
338 : const struct stepper_driver_api *api = (const struct stepper_driver_api *)dev->api;
339 :
340 : if (api->set_reference_position == NULL) {
341 : return -ENOSYS;
342 : }
343 : return api->set_reference_position(dev, value);
344 : }
345 :
346 : /**
347 : * @brief Get the actual a.k.a reference position of the stepper
348 : *
349 : * @param dev pointer to the stepper motor controller instance
350 : * @param value The actual position to get in micro_steps
351 : *
352 : * @retval -EIO General input / output error
353 : * @retval -ENOSYS If not implemented by device driver
354 : * @retval 0 Success
355 : */
356 1 : __syscall int stepper_get_actual_position(const struct device *dev, int32_t *value);
357 :
358 : static inline int z_impl_stepper_get_actual_position(const struct device *dev, int32_t *value)
359 : {
360 : const struct stepper_driver_api *api = (const struct stepper_driver_api *)dev->api;
361 :
362 : if (api->get_actual_position == NULL) {
363 : return -ENOSYS;
364 : }
365 : return api->get_actual_position(dev, value);
366 : }
367 :
368 : /**
369 : * @brief Set the absolute target position of the stepper
370 : *
371 : * @details The motor will move to the given micro_steps position from the reference position.
372 : * This function is non-blocking.
373 : *
374 : * @param dev pointer to the stepper motor controller instance
375 : * @param micro_steps target position to set in micro_steps
376 : *
377 : * @retval -EIO General input / output error
378 : * @retval -ENOSYS If not implemented by device driver
379 : * @retval 0 Success
380 : */
381 1 : __syscall int stepper_move_to(const struct device *dev, int32_t micro_steps);
382 :
383 : static inline int z_impl_stepper_move_to(const struct device *dev, const int32_t micro_steps)
384 : {
385 : const struct stepper_driver_api *api = (const struct stepper_driver_api *)dev->api;
386 :
387 : if (api->move_to == NULL) {
388 : return -ENOSYS;
389 : }
390 : return api->move_to(dev, micro_steps);
391 : }
392 :
393 : /**
394 : * @brief Check if the stepper motor is currently moving
395 : *
396 : * @param dev pointer to the stepper motor controller instance
397 : * @param is_moving Pointer to a boolean to store the moving status of the stepper motor
398 : *
399 : * @retval -EIO General input / output error
400 : * @retval -ENOSYS If not implemented by device driver
401 : * @retval 0 Success
402 : */
403 1 : __syscall int stepper_is_moving(const struct device *dev, bool *is_moving);
404 :
405 : static inline int z_impl_stepper_is_moving(const struct device *dev, bool *is_moving)
406 : {
407 : const struct stepper_driver_api *api = (const struct stepper_driver_api *)dev->api;
408 :
409 : if (api->is_moving == NULL) {
410 : return -ENOSYS;
411 : }
412 : return api->is_moving(dev, is_moving);
413 : }
414 :
415 : /**
416 : * @brief Run the stepper with a given velocity in a given direction
417 : *
418 : * @details If velocity > 0, motor shall be set into motion and run incessantly until and unless
419 : * stalled or stopped using some other command, for instance, motor_enable(false).
420 : * This function is non-blocking.
421 : *
422 : * @param dev pointer to the stepper motor controller instance
423 : * @param direction The direction to set
424 : * @param velocity The velocity to set in microsteps per second
425 : * - > 0: Run the stepper with the given velocity in a given direction
426 : * - 0: Stop the stepper
427 : *
428 : * @retval -EIO General input / output error
429 : * @retval -ENOSYS If not implemented by device driver
430 : * @retval 0 Success
431 : */
432 1 : __syscall int stepper_run(const struct device *dev, enum stepper_direction direction,
433 : uint32_t velocity);
434 :
435 : static inline int z_impl_stepper_run(const struct device *dev,
436 : const enum stepper_direction direction,
437 : const uint32_t velocity)
438 : {
439 : const struct stepper_driver_api *api = (const struct stepper_driver_api *)dev->api;
440 :
441 : if (api->run == NULL) {
442 : return -ENOSYS;
443 : }
444 : return api->run(dev, direction, velocity);
445 : }
446 :
447 : /**
448 : * @brief Set the callback function to be called when a stepper event occurs
449 : *
450 : * @param dev pointer to the stepper motor controller instance
451 : * @param callback Callback function to be called when a stepper event occurs
452 : * passing NULL will disable the callback
453 : * @param user_data User data to be passed to the callback function
454 : *
455 : * @retval -ENOSYS If not implemented by device driver
456 : * @retval 0 Success
457 : */
458 1 : __syscall int stepper_set_event_callback(const struct device *dev,
459 : stepper_event_callback_t callback, void *user_data);
460 :
461 : static inline int z_impl_stepper_set_event_callback(const struct device *dev,
462 : stepper_event_callback_t callback,
463 : void *user_data)
464 : {
465 : const struct stepper_driver_api *api = (const struct stepper_driver_api *)dev->api;
466 :
467 : if (api->set_event_callback == NULL) {
468 : return -ENOSYS;
469 : }
470 : return api->set_event_callback(dev, callback, user_data);
471 : }
472 :
473 : /**
474 : * @}
475 : */
476 :
477 : #ifdef __cplusplus
478 : }
479 : #endif
480 :
481 : #include <zephyr/syscalls/stepper.h>
482 :
483 : #endif /* ZEPHYR_INCLUDE_DRIVERS_STEPPER_H_ */
|