blob: df784840067978604d3d264396d7ca9378ff10ca [file] [log] [blame]
/**
* @file drivers/stepper.h
*
* @brief Public API for Stepper Driver
*
*/
/*
* SPDX-FileCopyrightText: Copyright (c) 2024 Carl Zeiss Meditec AG
* SPDX-License-Identifier: Apache-2.0
*/
#ifndef ZEPHYR_INCLUDE_DRIVERS_STEPPER_H_
#define ZEPHYR_INCLUDE_DRIVERS_STEPPER_H_
/**
* @brief Stepper Controller Interface
* @defgroup stepper_interface Stepper Controller Interface
* @ingroup io_interfaces
* @{
*/
#include <zephyr/kernel.h>
#include <zephyr/device.h>
#include <errno.h>
#ifdef __cplusplus
extern "C" {
#endif
#define MICRO_STEP_RES_INDEX(res) LOG2(res)
/**
* @brief Stepper Motor micro step resolution options
*/
enum stepper_micro_step_resolution {
/** Full step resolution */
STEPPER_MICRO_STEP_1 = 1,
/** 2 micro steps per full step */
STEPPER_MICRO_STEP_2 = 2,
/** 4 micro steps per full step */
STEPPER_MICRO_STEP_4 = 4,
/** 8 micro steps per full step */
STEPPER_MICRO_STEP_8 = 8,
/** 16 micro steps per full step */
STEPPER_MICRO_STEP_16 = 16,
/** 32 micro steps per full step */
STEPPER_MICRO_STEP_32 = 32,
/** 64 micro steps per full step */
STEPPER_MICRO_STEP_64 = 64,
/** 128 micro steps per full step */
STEPPER_MICRO_STEP_128 = 128,
/** 256 micro steps per full step */
STEPPER_MICRO_STEP_256 = 256,
};
/**
* @brief Stepper Motor direction options
*/
enum stepper_direction {
/** Negative direction */
STEPPER_DIRECTION_NEGATIVE = 0,
/** Positive direction */
STEPPER_DIRECTION_POSITIVE = 1,
};
/**
* @brief Stepper Motor run mode options
*/
enum stepper_run_mode {
/** Hold Mode */
STEPPER_RUN_MODE_HOLD = 0,
/** Position Mode*/
STEPPER_RUN_MODE_POSITION = 1,
/** Velocity Mode */
STEPPER_RUN_MODE_VELOCITY = 2,
};
/**
* @brief Stepper Events
*/
enum stepper_event {
/** Steps set using move or set_target_position have been executed */
STEPPER_EVENT_STEPS_COMPLETED = 0,
/** Stall detected */
STEPPER_EVENT_STALL_DETECTED = 1,
/** Left end switch status changes to pressed */
STEPPER_EVENT_LEFT_END_STOP_DETECTED = 2,
/** Right end switch status changes to pressed */
STEPPER_EVENT_RIGHT_END_STOP_DETECTED = 3,
};
/**
* @cond INTERNAL_HIDDEN
*
* Stepper motor controller driver API definition and system call entry points.
*
*/
/**
* @brief enable or disable the stepper motor controller.
*
* @see stepper_enable() for details.
*/
typedef int (*stepper_enable_t)(const struct device *dev, const bool enable);
/**
* @brief Move the stepper motor by a given number of micro_steps.
*
* @see stepper_move() for details.
*/
typedef int (*stepper_move_t)(const struct device *dev, const int32_t micro_steps);
/**
* @brief Set the max velocity in micro_steps per seconds.
*
* @see stepper_set_max_velocity() for details.
*/
typedef int (*stepper_set_max_velocity_t)(const struct device *dev,
const uint32_t micro_steps_per_second);
/**
* @brief Set the micro-step resolution
*
* @see stepper_set_micro_step_res() for details.
*/
typedef int (*stepper_set_micro_step_res_t)(const struct device *dev,
const enum stepper_micro_step_resolution resolution);
/**
* @brief Get the micro-step resolution
*
* @see stepper_get_micro_step_res() for details.
*/
typedef int (*stepper_get_micro_step_res_t)(const struct device *dev,
enum stepper_micro_step_resolution *resolution);
/**
* @brief Set the actual a.k.a reference position of the stepper
*
* @see stepper_set_actual_position() for details.
*/
typedef int (*stepper_set_actual_position_t)(const struct device *dev, const int32_t value);
/**
* @brief Get the actual a.k.a reference position of the stepper
*
* @see stepper_get_actual_position() for details.
*/
typedef int (*stepper_get_actual_position_t)(const struct device *dev, int32_t *value);
/**
* @brief Set the absolute target position of the stepper
*
* @see stepper_set_target_position() for details.
*/
typedef int (*stepper_set_target_position_t)(const struct device *dev, const int32_t value);
/**
* @brief Is the target position fo the stepper reached
*
* @see stepper_is_moving() for details.
*/
typedef int (*stepper_is_moving_t)(const struct device *dev, bool *is_moving);
/**
* @brief Enable constant velocity mode for the stepper with a given velocity
*
* @see stepper_enable_constant_velocity_mode() for details.
*/
typedef int (*stepper_enable_constant_velocity_mode_t)(const struct device *dev,
const enum stepper_direction direction,
const uint32_t value);
/**
* @brief Callback function for stepper events
*/
typedef void (*stepper_event_callback_t)(const struct device *dev, const enum stepper_event event,
void *user_data);
/**
* @brief Set the callback function to be called when a stepper event occurs
*
* @see stepper_set_event_callback() for details.
*/
typedef int (*stepper_set_event_callback_t)(const struct device *dev,
stepper_event_callback_t callback, void *user_data);
/**
* @brief Stepper Motor Controller API
*/
__subsystem struct stepper_driver_api {
stepper_enable_t enable;
stepper_move_t move;
stepper_set_max_velocity_t set_max_velocity;
stepper_set_micro_step_res_t set_micro_step_res;
stepper_get_micro_step_res_t get_micro_step_res;
stepper_set_actual_position_t set_actual_position;
stepper_get_actual_position_t get_actual_position;
stepper_set_target_position_t set_target_position;
stepper_is_moving_t is_moving;
stepper_enable_constant_velocity_mode_t enable_constant_velocity_mode;
stepper_set_event_callback_t set_event_callback;
};
/**
* @endcond
*/
/**
* @brief Enable or Disable Motor Controller
*
* @param dev pointer to the stepper motor controller instance
* @param enable Input enable or disable motor controller
*
* @retval -EIO Error during Enabling
* @retval 0 Success
*/
__syscall int stepper_enable(const struct device *dev, const bool enable);
static inline int z_impl_stepper_enable(const struct device *dev, const bool enable)
{
const struct stepper_driver_api *api = (const struct stepper_driver_api *)dev->api;
return api->enable(dev, enable);
}
/**
* @brief Set the micro_steps to be moved from the current position i.e. relative movement
*
* @param dev pointer to the stepper motor controller instance
* @param micro_steps target micro_steps to be moved from the current position
*
* @retval -EIO General input / output error
* @retval 0 Success
*/
__syscall int stepper_move(const struct device *dev, int32_t micro_steps);
static inline int z_impl_stepper_move(const struct device *dev, const int32_t micro_steps)
{
const struct stepper_driver_api *api = (const struct stepper_driver_api *)dev->api;
return api->move(dev, micro_steps);
}
/**
* @brief Set the target velocity to be reached by the motor
*
* @details For controllers such as DRV8825 where you
* toggle the STEP Pin, the pulse_length would have to be calculated based on this parameter in the
* driver. For controllers where velocity can be set, this parameter corresponds to max_velocity
* @note Setting max velocity does not set the motor into motion, a combination of set_max_velocity
* and move is required to set the motor into motion.
*
* @param dev pointer to the stepper motor controller instance
* @param micro_steps_per_second speed in micro_steps per second
*
* @retval -EIO General input / output error
* @retval -EINVAL If the requested velocity is not supported
* @retval 0 Success
*/
__syscall int stepper_set_max_velocity(const struct device *dev, uint32_t micro_steps_per_second);
static inline int z_impl_stepper_set_max_velocity(const struct device *dev,
const uint32_t micro_steps_per_second)
{
const struct stepper_driver_api *api = (const struct stepper_driver_api *)dev->api;
return api->set_max_velocity(dev, micro_steps_per_second);
}
/**
* @brief Set the microstep resolution in stepper motor controller
*
* @param dev pointer to the stepper motor controller instance
* @param resolution microstep resolution
*
* @retval -EIO General input / output error
* @retval -ENOSYS If not implemented by device driver
* @retval -ENOTSUP If the requested resolution is not supported
* @retval 0 Success
*/
__syscall int stepper_set_micro_step_res(const struct device *dev,
enum stepper_micro_step_resolution resolution);
static inline int z_impl_stepper_set_micro_step_res(const struct device *dev,
enum stepper_micro_step_resolution resolution)
{
const struct stepper_driver_api *api = (const struct stepper_driver_api *)dev->api;
if (api->set_micro_step_res == NULL) {
return -ENOSYS;
}
return api->set_micro_step_res(dev, resolution);
}
/**
* @brief Get the microstep resolution in stepper motor controller
*
* @param dev pointer to the stepper motor controller instance
* @param resolution microstep resolution
*
* @retval -EIO General input / output error
* @retval -ENOSYS If not implemented by device driver
* @retval 0 Success
*/
__syscall int stepper_get_micro_step_res(const struct device *dev,
enum stepper_micro_step_resolution *resolution);
static inline int z_impl_stepper_get_micro_step_res(const struct device *dev,
enum stepper_micro_step_resolution *resolution)
{
const struct stepper_driver_api *api = (const struct stepper_driver_api *)dev->api;
if (api->get_micro_step_res == NULL) {
return -ENOSYS;
}
return api->get_micro_step_res(dev, resolution);
}
/**
* @brief Set the actual a.k.a reference position of the stepper
*
* @param dev Pointer to the stepper motor controller instance.
* @param value The reference position to set in micro-steps.
*
* @retval -EIO General input / output error
* @retval -ENOSYS If not implemented by device driver
* @retval 0 Success
*/
__syscall int stepper_set_actual_position(const struct device *dev, int32_t value);
static inline int z_impl_stepper_set_actual_position(const struct device *dev, const int32_t value)
{
const struct stepper_driver_api *api = (const struct stepper_driver_api *)dev->api;
if (api->set_actual_position == NULL) {
return -ENOSYS;
}
return api->set_actual_position(dev, value);
}
/**
* @brief Get the actual a.k.a reference position of the stepper
*
* @param dev pointer to the stepper motor controller instance
* @param value The actual position to get in micro_steps
*
* @retval -EIO General input / output error
* @retval -ENOSYS If not implemented by device driver
* @retval 0 Success
*/
__syscall int stepper_get_actual_position(const struct device *dev, int32_t *value);
static inline int z_impl_stepper_get_actual_position(const struct device *dev, int32_t *value)
{
const struct stepper_driver_api *api = (const struct stepper_driver_api *)dev->api;
if (api->get_actual_position == NULL) {
return -ENOSYS;
}
return api->get_actual_position(dev, value);
}
/**
* @brief Set the absolute target position of the stepper
*
* @param dev pointer to the stepper motor controller instance
* @param value target position to set in micro_steps
*
* @retval -EIO General input / output error
* @retval -ENOSYS If not implemented by device driver
* @retval 0 Success
*/
__syscall int stepper_set_target_position(const struct device *dev, int32_t value);
static inline int z_impl_stepper_set_target_position(const struct device *dev, const int32_t value)
{
const struct stepper_driver_api *api = (const struct stepper_driver_api *)dev->api;
if (api->set_target_position == NULL) {
return -ENOSYS;
}
return api->set_target_position(dev, value);
}
/**
* @brief Check if the stepper motor is currently moving
*
* @param dev pointer to the stepper motor controller instance
* @param is_moving Pointer to a boolean to store the moving status of the stepper motor
*
* @retval -EIO General input / output error
* @retval -ENOSYS If not implemented by device driver
* @retval 0 Success
*/
__syscall int stepper_is_moving(const struct device *dev, bool *is_moving);
static inline int z_impl_stepper_is_moving(const struct device *dev, bool *is_moving)
{
const struct stepper_driver_api *api = (const struct stepper_driver_api *)dev->api;
if (api->is_moving == NULL) {
return -ENOSYS;
}
return api->is_moving(dev, is_moving);
}
/**
* @brief Enable constant velocity mode for the stepper with a given velocity
*
* @details activate constant velocity mode with the given velocity in micro_steps_per_second.
* If velocity > 0, motor shall be set into motion and run incessantly until and unless stalled or
* stopped using some other command, for instance, motor_enable(false).
*
* @param dev pointer to the stepper motor controller instance
* @param direction The direction to set
* @param value The velocity to set in steps per second where one step is dependent on the current
* microstepping resolution:
* > 0: Enable constant velocity mode with the given velocity in a given direction
* 0: Disable constant velocity mode
*
* @retval -EIO General input / output error
* @retval -ENOSYS If not implemented by device driver
* @retval 0 Success
*/
__syscall int stepper_enable_constant_velocity_mode(const struct device *dev,
enum stepper_direction direction,
uint32_t value);
static inline int z_impl_stepper_enable_constant_velocity_mode(
const struct device *dev, const enum stepper_direction direction, const uint32_t value)
{
const struct stepper_driver_api *api = (const struct stepper_driver_api *)dev->api;
if (api->enable_constant_velocity_mode == NULL) {
return -ENOSYS;
}
return api->enable_constant_velocity_mode(dev, direction, value);
}
/**
* @brief Set the callback function to be called when a stepper event occurs
*
* @param dev pointer to the stepper motor controller instance
* @param callback Callback function to be called when a stepper event occurs
* passing NULL will disable the callback
* @param user_data User data to be passed to the callback function
*
* @retval -ENOSYS If not implemented by device driver
* @retval 0 Success
*/
__syscall int stepper_set_event_callback(const struct device *dev,
stepper_event_callback_t callback, void *user_data);
static inline int z_impl_stepper_set_event_callback(const struct device *dev,
stepper_event_callback_t callback,
void *user_data)
{
const struct stepper_driver_api *api = (const struct stepper_driver_api *)dev->api;
if (api->set_event_callback == NULL) {
return -ENOSYS;
}
return api->set_event_callback(dev, callback, user_data);
}
/**
* @}
*/
#ifdef __cplusplus
}
#endif
#include <zephyr/syscalls/stepper.h>
#endif /* ZEPHYR_INCLUDE_DRIVERS_STEPPER_H_ */