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