drivers: stepper: update drivers as per the api changes
This commit deprecates passing of async signal in functions such as move and set_target_position. As per the new API, the async signal has to be set via set_async_signal. If RAMPSTAT_POLL is activated then enable_constant_velocity_mode would be able to raise signals like END_STOP_DETECTED & SENSORLESS_STALL_DETECTED. This commit also adjusts shell script in order to test these signals. Signed-off-by: Jilay Pandya <jilay.pandya@zeiss.com>
This commit is contained in:
parent
4f18d64b30
commit
ecada895da
7 changed files with 132 additions and 176 deletions
|
|
@ -6,7 +6,6 @@ menu "GPIO stepper driver"
|
|||
config GPIO_STEPPER
|
||||
bool "Activate driver for gpio stepper control"
|
||||
depends on DT_HAS_GPIO_STEPPERS_ENABLED
|
||||
select POLL
|
||||
default y
|
||||
help
|
||||
GPIO Stepper driver for stepper motor control with darlington arrays or dual H-bridge.
|
||||
|
|
|
|||
|
|
@ -37,7 +37,6 @@ config STEPPER_ADI_TMC5041
|
|||
config STEPPER_ADI_TMC5041_RAMPSTAT_POLL
|
||||
bool "TMC5041 poll ramp status"
|
||||
depends on STEPPER_ADI_TMC5041
|
||||
select POLL
|
||||
default y
|
||||
help
|
||||
When enabled, the ramp status will be polled on TMC5041, to check for events:
|
||||
|
|
|
|||
|
|
@ -5,7 +5,7 @@
|
|||
|
||||
#define DT_DRV_COMPAT adi_tmc5041
|
||||
|
||||
#include "stdlib.h"
|
||||
#include <stdlib.h>
|
||||
|
||||
#include <zephyr/drivers/stepper.h>
|
||||
#include <zephyr/drivers/stepper/stepper_trinamic.h>
|
||||
|
|
@ -35,7 +35,8 @@ struct tmc5041_stepper_data {
|
|||
#endif
|
||||
/* device pointer required to access config in k_work */
|
||||
const struct device *stepper;
|
||||
struct k_poll_signal *async_signal;
|
||||
stepper_event_callback_t callback;
|
||||
void *event_cb_user_data;
|
||||
};
|
||||
|
||||
struct tmc5041_stepper_config {
|
||||
|
|
@ -103,18 +104,14 @@ static void calculate_velocity_from_hz_to_fclk(const struct device *dev, const u
|
|||
velocity_hz, *velocity_fclk);
|
||||
}
|
||||
|
||||
static void set_async_signal(const struct device *dev, struct k_poll_signal *async)
|
||||
static int tmc5041_stepper_set_event_callback(const struct device *dev,
|
||||
stepper_event_callback_t callback, void *user_data)
|
||||
{
|
||||
struct tmc5041_stepper_data *data = dev->data;
|
||||
|
||||
if (!async) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (data->async_signal) {
|
||||
k_poll_signal_reset(data->async_signal);
|
||||
}
|
||||
data->async_signal = async;
|
||||
data->callback = callback;
|
||||
data->event_cb_user_data = user_data;
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int stallguard_enable(const struct device *dev, const bool enable)
|
||||
|
|
@ -180,19 +177,15 @@ static void stallguard_work_handler(struct k_work *work)
|
|||
|
||||
#ifdef CONFIG_STEPPER_ADI_TMC5041_RAMPSTAT_POLL
|
||||
|
||||
static void emit_signal(struct k_poll_signal *async_signal, const enum stepper_signal_result signal)
|
||||
static void execute_callback(const struct device *dev, const enum stepper_event event)
|
||||
{
|
||||
int err;
|
||||
struct tmc5041_stepper_data *data = dev->data;
|
||||
|
||||
if (!async_signal) {
|
||||
LOG_WRN("Async signal is NULL");
|
||||
if (!data->callback) {
|
||||
LOG_WRN_ONCE("No callback registered");
|
||||
return;
|
||||
}
|
||||
|
||||
err = k_poll_signal_raise(async_signal, signal);
|
||||
if (err != 0) {
|
||||
LOG_ERR("Failed to raise signal %d error %d", signal, err);
|
||||
}
|
||||
data->callback(dev, event);
|
||||
}
|
||||
|
||||
static void rampstat_work_handler(struct k_work *work)
|
||||
|
|
@ -237,26 +230,25 @@ static void rampstat_work_handler(struct k_work *work)
|
|||
|
||||
case TMC5041_STOP_LEFT_EVENT:
|
||||
LOG_DBG("RAMPSTAT %s:Left end-stop detected", stepper_data->stepper->name);
|
||||
emit_signal(stepper_data->async_signal,
|
||||
STEPPER_SIGNAL_LEFT_END_STOP_DETECTED);
|
||||
execute_callback(stepper_data->stepper,
|
||||
STEPPER_EVENT_LEFT_END_STOP_DETECTED);
|
||||
break;
|
||||
|
||||
case TMC5041_STOP_RIGHT_EVENT:
|
||||
LOG_DBG("RAMPSTAT %s:Right end-stop detected", stepper_data->stepper->name);
|
||||
emit_signal(stepper_data->async_signal,
|
||||
STEPPER_SIGNAL_RIGHT_END_STOP_DETECTED);
|
||||
execute_callback(stepper_data->stepper,
|
||||
STEPPER_EVENT_RIGHT_END_STOP_DETECTED);
|
||||
break;
|
||||
|
||||
case TMC5041_POS_REACHED_EVENT:
|
||||
LOG_DBG("RAMPSTAT %s:Position reached", stepper_data->stepper->name);
|
||||
emit_signal(stepper_data->async_signal, STEPPER_SIGNAL_STEPS_COMPLETED);
|
||||
execute_callback(stepper_data->stepper, STEPPER_EVENT_STEPS_COMPLETED);
|
||||
break;
|
||||
|
||||
case TMC5041_STOP_SG_EVENT:
|
||||
LOG_DBG("RAMPSTAT %s:Stall detected", stepper_data->stepper->name);
|
||||
stallguard_enable(stepper_data->stepper, false);
|
||||
emit_signal(stepper_data->async_signal,
|
||||
STEPPER_SIGNAL_SENSORLESS_STALL_DETECTED);
|
||||
execute_callback(stepper_data->stepper, STEPPER_EVENT_STALL_DETECTED);
|
||||
break;
|
||||
default:
|
||||
LOG_ERR("Illegal ramp stat bit field");
|
||||
|
|
@ -314,15 +306,12 @@ static int tmc5041_stepper_is_moving(const struct device *dev, bool *is_moving)
|
|||
return 0;
|
||||
}
|
||||
|
||||
static int tmc5041_stepper_move(const struct device *dev, const int32_t steps,
|
||||
struct k_poll_signal *async)
|
||||
static int tmc5041_stepper_move(const struct device *dev, const int32_t steps)
|
||||
{
|
||||
const struct tmc5041_stepper_config *config = dev->config;
|
||||
struct tmc5041_stepper_data *data = dev->data;
|
||||
int err;
|
||||
|
||||
set_async_signal(dev, async);
|
||||
|
||||
if (config->is_sg_enabled) {
|
||||
err = stallguard_enable(dev, false);
|
||||
if (err != 0) {
|
||||
|
|
@ -355,8 +344,11 @@ static int tmc5041_stepper_move(const struct device *dev, const int32_t steps,
|
|||
K_MSEC(config->sg_velocity_check_interval_ms));
|
||||
}
|
||||
#ifdef CONFIG_STEPPER_ADI_TMC5041_RAMPSTAT_POLL
|
||||
k_work_reschedule(&data->rampstat_callback_dwork,
|
||||
K_MSEC(CONFIG_STEPPER_ADI_TMC5041_RAMPSTAT_POLL_INTERVAL_IN_MSEC));
|
||||
if (data->callback) {
|
||||
k_work_reschedule(
|
||||
&data->rampstat_callback_dwork,
|
||||
K_MSEC(CONFIG_STEPPER_ADI_TMC5041_RAMPSTAT_POLL_INTERVAL_IN_MSEC));
|
||||
}
|
||||
#endif
|
||||
return 0;
|
||||
}
|
||||
|
|
@ -377,7 +369,7 @@ static int tmc5041_stepper_set_max_velocity(const struct device *dev, uint32_t v
|
|||
}
|
||||
|
||||
static int tmc5041_stepper_set_micro_step_res(const struct device *dev,
|
||||
enum micro_step_resolution res)
|
||||
enum stepper_micro_step_resolution res)
|
||||
{
|
||||
const struct tmc5041_stepper_config *config = dev->config;
|
||||
uint32_t reg_value;
|
||||
|
|
@ -403,7 +395,7 @@ static int tmc5041_stepper_set_micro_step_res(const struct device *dev,
|
|||
}
|
||||
|
||||
static int tmc5041_stepper_get_micro_step_res(const struct device *dev,
|
||||
enum micro_step_resolution *res)
|
||||
enum stepper_micro_step_resolution *res)
|
||||
{
|
||||
const struct tmc5041_stepper_config *config = dev->config;
|
||||
uint32_t reg_value;
|
||||
|
|
@ -452,16 +444,13 @@ static int tmc5041_stepper_get_actual_position(const struct device *dev, int32_t
|
|||
return 0;
|
||||
}
|
||||
|
||||
static int tmc5041_stepper_set_target_position(const struct device *dev, const int32_t position,
|
||||
struct k_poll_signal *async)
|
||||
static int tmc5041_stepper_set_target_position(const struct device *dev, const int32_t position)
|
||||
{
|
||||
LOG_DBG("Stepper motor controller %s set target position to %d", dev->name, position);
|
||||
const struct tmc5041_stepper_config *config = dev->config;
|
||||
struct tmc5041_stepper_data *data = dev->data;
|
||||
int err;
|
||||
|
||||
set_async_signal(dev, async);
|
||||
|
||||
if (config->is_sg_enabled) {
|
||||
stallguard_enable(dev, false);
|
||||
}
|
||||
|
|
@ -478,8 +467,11 @@ static int tmc5041_stepper_set_target_position(const struct device *dev, const i
|
|||
K_MSEC(config->sg_velocity_check_interval_ms));
|
||||
}
|
||||
#ifdef CONFIG_STEPPER_ADI_TMC5041_RAMPSTAT_POLL
|
||||
k_work_reschedule(&data->rampstat_callback_dwork,
|
||||
K_MSEC(CONFIG_STEPPER_ADI_TMC5041_RAMPSTAT_POLL_INTERVAL_IN_MSEC));
|
||||
if (data->callback) {
|
||||
k_work_reschedule(
|
||||
&data->rampstat_callback_dwork,
|
||||
K_MSEC(CONFIG_STEPPER_ADI_TMC5041_RAMPSTAT_POLL_INTERVAL_IN_MSEC));
|
||||
}
|
||||
#endif
|
||||
return 0;
|
||||
}
|
||||
|
|
@ -533,6 +525,13 @@ static int tmc5041_stepper_enable_constant_velocity_mode(const struct device *de
|
|||
k_work_reschedule(&data->stallguard_dwork,
|
||||
K_MSEC(config->sg_velocity_check_interval_ms));
|
||||
}
|
||||
#ifdef CONFIG_STEPPER_ADI_TMC5041_RAMPSTAT_POLL
|
||||
if (data->callback) {
|
||||
k_work_reschedule(
|
||||
&data->rampstat_callback_dwork,
|
||||
K_MSEC(CONFIG_STEPPER_ADI_TMC5041_RAMPSTAT_POLL_INTERVAL_IN_MSEC));
|
||||
}
|
||||
#endif
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
|
@ -730,7 +729,7 @@ static int tmc5041_stepper_init(const struct device *dev)
|
|||
.get_actual_position = tmc5041_stepper_get_actual_position, \
|
||||
.set_target_position = tmc5041_stepper_set_target_position, \
|
||||
.enable_constant_velocity_mode = tmc5041_stepper_enable_constant_velocity_mode, \
|
||||
};
|
||||
.set_event_callback = tmc5041_stepper_set_event_callback, };
|
||||
|
||||
#define TMC5041_STEPPER_DEFINE(child) \
|
||||
DEVICE_DT_DEFINE(child, tmc5041_stepper_init, NULL, &tmc5041_stepper_data_##child, \
|
||||
|
|
@ -744,7 +743,7 @@ static int tmc5041_stepper_init(const struct device *dev)
|
|||
static struct tmc5041_data tmc5041_data_##inst; \
|
||||
static const struct tmc5041_config tmc5041_config_##inst = { \
|
||||
.gconf = ( \
|
||||
(DT_INST_PROP(inst, poscmp_enable) << TMC5041_GCONF_POSCMP_ENABLE_SHIFT) |\
|
||||
(DT_INST_PROP(inst, poscmp_enable) << TMC5041_GCONF_POSCMP_ENABLE_SHIFT) | \
|
||||
(DT_INST_PROP(inst, test_mode) << TMC5041_GCONF_TEST_MODE_SHIFT) | \
|
||||
DT_INST_FOREACH_CHILD(inst, TMC5041_SHAFT_CONFIG) \
|
||||
(DT_INST_PROP(inst, lock_gconf) << TMC5041_LOCK_GCONF_SHIFT)), \
|
||||
|
|
|
|||
|
|
@ -15,7 +15,7 @@
|
|||
#define DT_DRV_COMPAT zephyr_fake_stepper
|
||||
|
||||
struct fake_stepper_data {
|
||||
enum micro_step_resolution micro_step_res;
|
||||
enum stepper_micro_step_resolution micro_step_res;
|
||||
int32_t actual_position;
|
||||
};
|
||||
|
||||
|
|
@ -23,29 +23,30 @@ DEFINE_FAKE_VALUE_FUNC(int, fake_stepper_enable, const struct device *, const bo
|
|||
|
||||
DEFINE_FAKE_VALUE_FUNC(int, fake_stepper_is_moving, const struct device *, bool *);
|
||||
|
||||
DEFINE_FAKE_VALUE_FUNC(int, fake_stepper_move, const struct device *, const int32_t,
|
||||
struct k_poll_signal *);
|
||||
DEFINE_FAKE_VALUE_FUNC(int, fake_stepper_move, const struct device *, const int32_t);
|
||||
|
||||
DEFINE_FAKE_VALUE_FUNC(int, fake_stepper_set_max_velocity, const struct device *, const uint32_t);
|
||||
|
||||
DEFINE_FAKE_VALUE_FUNC(int, fake_stepper_set_micro_step_res, const struct device *,
|
||||
const enum micro_step_resolution);
|
||||
const enum stepper_micro_step_resolution);
|
||||
|
||||
DEFINE_FAKE_VALUE_FUNC(int, fake_stepper_get_micro_step_res, const struct device *,
|
||||
enum micro_step_resolution *);
|
||||
enum stepper_micro_step_resolution *);
|
||||
|
||||
DEFINE_FAKE_VALUE_FUNC(int, fake_stepper_set_actual_position, const struct device *, const int32_t);
|
||||
|
||||
DEFINE_FAKE_VALUE_FUNC(int, fake_stepper_get_actual_position, const struct device *, int32_t *);
|
||||
|
||||
DEFINE_FAKE_VALUE_FUNC(int, fake_stepper_set_target_position, const struct device *, const int32_t,
|
||||
struct k_poll_signal *);
|
||||
DEFINE_FAKE_VALUE_FUNC(int, fake_stepper_set_target_position, const struct device *, const int32_t);
|
||||
|
||||
DEFINE_FAKE_VALUE_FUNC(int, fake_stepper_enable_constant_velocity_mode, const struct device *,
|
||||
const enum stepper_direction, const uint32_t);
|
||||
|
||||
DEFINE_FAKE_VALUE_FUNC(int, fake_stepper_set_event_callback, const struct device *,
|
||||
stepper_event_callback_t, void *);
|
||||
|
||||
static int fake_stepper_set_micro_step_res_delegate(const struct device *dev,
|
||||
const enum micro_step_resolution res)
|
||||
const enum stepper_micro_step_resolution res)
|
||||
{
|
||||
struct fake_stepper_data *data = dev->data;
|
||||
|
||||
|
|
@ -55,7 +56,7 @@ static int fake_stepper_set_micro_step_res_delegate(const struct device *dev,
|
|||
}
|
||||
|
||||
static int fake_stepper_get_micro_step_res_delegate(const struct device *dev,
|
||||
enum micro_step_resolution *res)
|
||||
enum stepper_micro_step_resolution *res)
|
||||
{
|
||||
struct fake_stepper_data *data = dev->data;
|
||||
|
||||
|
|
@ -134,6 +135,7 @@ static const struct stepper_driver_api fake_stepper_driver_api = {
|
|||
.get_actual_position = fake_stepper_get_actual_position,
|
||||
.set_target_position = fake_stepper_set_target_position,
|
||||
.enable_constant_velocity_mode = fake_stepper_enable_constant_velocity_mode,
|
||||
.set_event_callback = fake_stepper_set_event_callback,
|
||||
};
|
||||
|
||||
#define FAKE_STEPPER_INIT(inst) \
|
||||
|
|
|
|||
|
|
@ -34,10 +34,11 @@ struct gpio_stepper_data {
|
|||
uint8_t step_gap;
|
||||
uint8_t coil_charge;
|
||||
struct k_work_delayable stepper_dwork;
|
||||
struct k_poll_signal *async_signal;
|
||||
stepper_event_callback_t callback;
|
||||
int32_t actual_position;
|
||||
uint32_t delay_in_us;
|
||||
int32_t step_count;
|
||||
void *event_cb_user_data;
|
||||
};
|
||||
|
||||
static int stepper_motor_set_coil_charge(const struct device *dev)
|
||||
|
|
@ -79,10 +80,11 @@ static void update_remaining_steps(struct gpio_stepper_data *data)
|
|||
data->step_count++;
|
||||
(void)k_work_reschedule(&data->stepper_dwork, K_USEC(data->delay_in_us));
|
||||
} else {
|
||||
if (data->async_signal) {
|
||||
(void)k_poll_signal_raise(data->async_signal,
|
||||
STEPPER_SIGNAL_STEPS_COMPLETED);
|
||||
if (!data->callback) {
|
||||
LOG_WRN_ONCE("No callback set");
|
||||
return;
|
||||
}
|
||||
data->callback(data->dev, STEPPER_EVENT_STEPS_COMPLETED);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -125,10 +127,10 @@ static void stepper_work_step_handler(struct k_work *work)
|
|||
|
||||
K_SPINLOCK(&data->lock) {
|
||||
switch (data->run_mode) {
|
||||
case STEPPER_POSITION_MODE:
|
||||
case STEPPER_RUN_MODE_POSITION:
|
||||
position_mode_task(data->dev);
|
||||
break;
|
||||
case STEPPER_VELOCITY_MODE:
|
||||
case STEPPER_RUN_MODE_VELOCITY:
|
||||
velocity_mode_task(data->dev);
|
||||
break;
|
||||
default:
|
||||
|
|
@ -138,8 +140,7 @@ static void stepper_work_step_handler(struct k_work *work)
|
|||
}
|
||||
}
|
||||
|
||||
static int gpio_stepper_move(const struct device *dev, int32_t micro_steps,
|
||||
struct k_poll_signal *async)
|
||||
static int gpio_stepper_move(const struct device *dev, int32_t micro_steps)
|
||||
{
|
||||
struct gpio_stepper_data *data = dev->data;
|
||||
|
||||
|
|
@ -148,11 +149,7 @@ static int gpio_stepper_move(const struct device *dev, int32_t micro_steps,
|
|||
return -EINVAL;
|
||||
}
|
||||
K_SPINLOCK(&data->lock) {
|
||||
if (data->async_signal) {
|
||||
k_poll_signal_reset(data->async_signal);
|
||||
}
|
||||
data->async_signal = async;
|
||||
data->run_mode = STEPPER_POSITION_MODE;
|
||||
data->run_mode = STEPPER_RUN_MODE_POSITION;
|
||||
data->step_count = micro_steps;
|
||||
update_direction_from_step_count(data);
|
||||
(void)k_work_reschedule(&data->stepper_dwork, K_NO_WAIT);
|
||||
|
|
@ -180,8 +177,7 @@ static int gpio_stepper_get_actual_position(const struct device *dev, int32_t *p
|
|||
return 0;
|
||||
}
|
||||
|
||||
static int gpio_stepper_set_target_position(const struct device *dev, int32_t position,
|
||||
struct k_poll_signal *async)
|
||||
static int gpio_stepper_set_target_position(const struct device *dev, int32_t position)
|
||||
{
|
||||
struct gpio_stepper_data *data = dev->data;
|
||||
|
||||
|
|
@ -190,11 +186,7 @@ static int gpio_stepper_set_target_position(const struct device *dev, int32_t po
|
|||
return -EINVAL;
|
||||
}
|
||||
K_SPINLOCK(&data->lock) {
|
||||
if (data->async_signal) {
|
||||
k_poll_signal_reset(data->async_signal);
|
||||
}
|
||||
data->async_signal = async;
|
||||
data->run_mode = STEPPER_POSITION_MODE;
|
||||
data->run_mode = STEPPER_RUN_MODE_POSITION;
|
||||
data->step_count = position - data->actual_position;
|
||||
update_direction_from_step_count(data);
|
||||
(void)k_work_reschedule(&data->stepper_dwork, K_NO_WAIT);
|
||||
|
|
@ -239,7 +231,7 @@ static int gpio_stepper_enable_constant_velocity_mode(const struct device *dev,
|
|||
struct gpio_stepper_data *data = dev->data;
|
||||
|
||||
K_SPINLOCK(&data->lock) {
|
||||
data->run_mode = STEPPER_VELOCITY_MODE;
|
||||
data->run_mode = STEPPER_RUN_MODE_VELOCITY;
|
||||
data->direction = direction;
|
||||
if (value != 0) {
|
||||
data->delay_in_us = USEC_PER_SEC / value;
|
||||
|
|
@ -252,13 +244,13 @@ static int gpio_stepper_enable_constant_velocity_mode(const struct device *dev,
|
|||
}
|
||||
|
||||
static int gpio_stepper_set_micro_step_res(const struct device *dev,
|
||||
enum micro_step_resolution micro_step_res)
|
||||
enum stepper_micro_step_resolution micro_step_res)
|
||||
{
|
||||
struct gpio_stepper_data *data = dev->data;
|
||||
|
||||
K_SPINLOCK(&data->lock) {
|
||||
switch (micro_step_res) {
|
||||
case STEPPER_FULL_STEP:
|
||||
case STEPPER_MICRO_STEP_1:
|
||||
case STEPPER_MICRO_STEP_2:
|
||||
data->step_gap = MAX_MICRO_STEP_RES >> (micro_step_res - 1);
|
||||
break;
|
||||
|
|
@ -271,13 +263,25 @@ static int gpio_stepper_set_micro_step_res(const struct device *dev,
|
|||
}
|
||||
|
||||
static int gpio_stepper_get_micro_step_res(const struct device *dev,
|
||||
enum micro_step_resolution *micro_step_res)
|
||||
enum stepper_micro_step_resolution *micro_step_res)
|
||||
{
|
||||
struct gpio_stepper_data *data = dev->data;
|
||||
*micro_step_res = MAX_MICRO_STEP_RES >> (data->step_gap - 1);
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int gpio_stepper_set_event_callback(const struct device *dev,
|
||||
stepper_event_callback_t callback, void *user_data)
|
||||
{
|
||||
struct gpio_stepper_data *data = dev->data;
|
||||
|
||||
K_SPINLOCK(&data->lock) {
|
||||
data->callback = callback;
|
||||
}
|
||||
data->event_cb_user_data = user_data;
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int gpio_stepper_enable(const struct device *dev, bool enable)
|
||||
{
|
||||
struct gpio_stepper_data *data = dev->data;
|
||||
|
|
@ -335,7 +339,8 @@ static int gpio_stepper_motor_controller_init(const struct device *dev)
|
|||
.set_max_velocity = gpio_stepper_set_max_velocity, \
|
||||
.enable_constant_velocity_mode = gpio_stepper_enable_constant_velocity_mode, \
|
||||
.set_micro_step_res = gpio_stepper_set_micro_step_res, \
|
||||
.get_micro_step_res = gpio_stepper_get_micro_step_res};
|
||||
.get_micro_step_res = gpio_stepper_get_micro_step_res, \
|
||||
.set_event_callback = gpio_stepper_set_event_callback, };
|
||||
|
||||
#define GPIO_STEPPER_DEVICE_DEFINE(child) \
|
||||
DEVICE_DT_DEFINE(child, gpio_stepper_motor_controller_init, NULL, \
|
||||
|
|
|
|||
|
|
@ -8,7 +8,6 @@
|
|||
#include <zephyr/shell/shell.h>
|
||||
#include <zephyr/device.h>
|
||||
#include <zephyr/drivers/stepper.h>
|
||||
#include <stdlib.h>
|
||||
|
||||
#include <zephyr/logging/log.h>
|
||||
LOG_MODULE_REGISTER(stepper_shell, CONFIG_STEPPER_LOG_LEVEL);
|
||||
|
|
@ -21,7 +20,7 @@ enum {
|
|||
|
||||
struct stepper_microstep_map {
|
||||
const char *name;
|
||||
enum micro_step_resolution microstep;
|
||||
enum stepper_micro_step_resolution microstep;
|
||||
};
|
||||
|
||||
struct stepper_direction_map {
|
||||
|
|
@ -41,18 +40,26 @@ struct stepper_direction_map {
|
|||
.microstep = _microstep, \
|
||||
}
|
||||
|
||||
#ifdef CONFIG_STEPPER_SHELL_ASYNC
|
||||
|
||||
static struct k_poll_signal stepper_signal;
|
||||
static struct k_poll_event stepper_poll_event =
|
||||
K_POLL_EVENT_INITIALIZER(K_POLL_TYPE_SIGNAL, K_POLL_MODE_NOTIFY_ONLY, &stepper_signal);
|
||||
|
||||
static bool poll_thread_started;
|
||||
K_THREAD_STACK_DEFINE(poll_thread_stack, CONFIG_STEPPER_SHELL_THREAD_STACK_SIZE);
|
||||
static struct k_thread poll_thread;
|
||||
static int start_polling(const struct shell *sh);
|
||||
|
||||
#endif /* CONFIG_STEPPER_SHELL_ASYNC */
|
||||
static void print_callback(const struct device *dev, const enum stepper_event event)
|
||||
{
|
||||
switch (event) {
|
||||
case STEPPER_EVENT_STEPS_COMPLETED:
|
||||
LOG_INF("%s: Steps completed.", dev->name);
|
||||
break;
|
||||
case STEPPER_EVENT_STALL_DETECTED:
|
||||
LOG_INF("%s: Stall detected.", dev->name);
|
||||
break;
|
||||
case STEPPER_EVENT_LEFT_END_STOP_DETECTED:
|
||||
LOG_INF("%s: Left limit switch pressed.", dev->name);
|
||||
break;
|
||||
case STEPPER_EVENT_RIGHT_END_STOP_DETECTED:
|
||||
LOG_INF("%s: Right limit switch pressed.", dev->name);
|
||||
break;
|
||||
default:
|
||||
LOG_INF("%s: Unknown signal received.", dev->name);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
static const struct stepper_direction_map stepper_direction_map[] = {
|
||||
STEPPER_DIRECTION_MAP_ENTRY("positive", STEPPER_DIRECTION_POSITIVE),
|
||||
|
|
@ -60,7 +67,7 @@ static const struct stepper_direction_map stepper_direction_map[] = {
|
|||
};
|
||||
|
||||
static const struct stepper_microstep_map stepper_microstep_map[] = {
|
||||
STEPPER_MICROSTEP_MAP("1", STEPPER_FULL_STEP),
|
||||
STEPPER_MICROSTEP_MAP("1", STEPPER_MICRO_STEP_1),
|
||||
STEPPER_MICROSTEP_MAP("2", STEPPER_MICRO_STEP_2),
|
||||
STEPPER_MICROSTEP_MAP("4", STEPPER_MICRO_STEP_4),
|
||||
STEPPER_MICROSTEP_MAP("8", STEPPER_MICRO_STEP_8),
|
||||
|
|
@ -181,8 +188,7 @@ static int cmd_stepper_move(const struct shell *sh, size_t argc, char **argv)
|
|||
{
|
||||
const struct device *dev;
|
||||
int err = 0;
|
||||
struct k_poll_signal *poll_signal =
|
||||
COND_CODE_1(CONFIG_STEPPER_SHELL_ASYNC, (&stepper_signal), (NULL));
|
||||
|
||||
int32_t micro_steps = shell_strtol(argv[ARG_IDX_PARAM], 10, &err);
|
||||
|
||||
if (err < 0) {
|
||||
|
|
@ -194,11 +200,12 @@ static int cmd_stepper_move(const struct shell *sh, size_t argc, char **argv)
|
|||
return err;
|
||||
}
|
||||
|
||||
#ifdef CONFIG_STEPPER_SHELL_ASYNC
|
||||
start_polling(sh);
|
||||
#endif /* CONFIG_STEPPER_SHELL_ASYNC */
|
||||
err = stepper_set_callback(dev, print_callback, NULL);
|
||||
if (err != 0) {
|
||||
shell_error(sh, "Failed to set callback: %d", err);
|
||||
}
|
||||
|
||||
err = stepper_move(dev, micro_steps, poll_signal);
|
||||
err = stepper_move(dev, micro_steps);
|
||||
if (err) {
|
||||
shell_error(sh, "Error: %d", err);
|
||||
}
|
||||
|
|
@ -232,7 +239,7 @@ static int cmd_stepper_set_max_velocity(const struct shell *sh, size_t argc, cha
|
|||
static int cmd_stepper_set_micro_step_res(const struct shell *sh, size_t argc, char **argv)
|
||||
{
|
||||
const struct device *dev;
|
||||
enum micro_step_resolution resolution;
|
||||
enum stepper_micro_step_resolution resolution;
|
||||
int err = -EINVAL;
|
||||
|
||||
for (int i = 0; i < ARRAY_SIZE(stepper_microstep_map); i++) {
|
||||
|
|
@ -264,7 +271,7 @@ static int cmd_stepper_get_micro_step_res(const struct shell *sh, size_t argc, c
|
|||
{
|
||||
const struct device *dev;
|
||||
int err;
|
||||
enum micro_step_resolution micro_step_res;
|
||||
enum stepper_micro_step_resolution micro_step_res;
|
||||
|
||||
err = parse_device_arg(sh, argv, &dev);
|
||||
if (err < 0) {
|
||||
|
|
@ -335,19 +342,17 @@ static int cmd_stepper_set_target_position(const struct shell *sh, size_t argc,
|
|||
return err;
|
||||
}
|
||||
|
||||
struct k_poll_signal *poll_signal =
|
||||
COND_CODE_1(CONFIG_STEPPER_SHELL_ASYNC, (&stepper_signal), (NULL));
|
||||
|
||||
err = parse_device_arg(sh, argv, &dev);
|
||||
if (err < 0) {
|
||||
return err;
|
||||
}
|
||||
|
||||
#ifdef CONFIG_STEPPER_SHELL_ASYNC
|
||||
start_polling(sh);
|
||||
#endif /* CONFIG_STEPPER_SHELL_ASYNC */
|
||||
err = stepper_set_callback(dev, print_callback, NULL);
|
||||
if (err != 0) {
|
||||
shell_error(sh, "Failed to set callback: %d", err);
|
||||
}
|
||||
|
||||
err = stepper_set_target_position(dev, position, poll_signal);
|
||||
err = stepper_set_target_position(dev, position);
|
||||
if (err) {
|
||||
shell_error(sh, "Error: %d", err);
|
||||
}
|
||||
|
|
@ -385,6 +390,11 @@ static int cmd_stepper_enable_constant_velocity_mode(const struct shell *sh, siz
|
|||
return err;
|
||||
}
|
||||
|
||||
err = stepper_set_callback(dev, print_callback, NULL);
|
||||
if (err != 0) {
|
||||
shell_error(sh, "Failed to set callback: %d", err);
|
||||
}
|
||||
|
||||
err = stepper_enable_constant_velocity_mode(dev, direction, velocity);
|
||||
if (err) {
|
||||
shell_error(sh, "Error: %d", err);
|
||||
|
|
@ -400,7 +410,7 @@ static int cmd_stepper_info(const struct shell *sh, size_t argc, char **argv)
|
|||
int err;
|
||||
bool is_moving;
|
||||
int32_t actual_position;
|
||||
enum micro_step_resolution micro_step_res;
|
||||
enum stepper_micro_step_resolution micro_step_res;
|
||||
|
||||
err = parse_device_arg(sh, argv, &dev);
|
||||
if (err < 0) {
|
||||
|
|
@ -434,66 +444,6 @@ static int cmd_stepper_info(const struct shell *sh, size_t argc, char **argv)
|
|||
return 0;
|
||||
}
|
||||
|
||||
#ifdef CONFIG_STEPPER_SHELL_ASYNC
|
||||
|
||||
static void stepper_poll_thread(void *p1, void *p2, void *p3)
|
||||
{
|
||||
ARG_UNUSED(p2);
|
||||
ARG_UNUSED(p3);
|
||||
const struct shell *sh = p1;
|
||||
|
||||
while (1) {
|
||||
k_poll(&stepper_poll_event, 1, K_FOREVER);
|
||||
|
||||
switch (stepper_poll_event.signal->result) {
|
||||
case STEPPER_SIGNAL_STEPS_COMPLETED:
|
||||
shell_fprintf_info(sh, "Stepper: All steps completed.\n");
|
||||
break;
|
||||
case STEPPER_SIGNAL_SENSORLESS_STALL_DETECTED:
|
||||
shell_fprintf_info(sh, "Stepper: Sensorless stall detected.\n");
|
||||
break;
|
||||
case STEPPER_SIGNAL_LEFT_END_STOP_DETECTED:
|
||||
shell_fprintf_info(sh, "Stepper: Left limit switch pressed.\n");
|
||||
break;
|
||||
case STEPPER_SIGNAL_RIGHT_END_STOP_DETECTED:
|
||||
shell_fprintf_normal(sh, "Stepper: Right limit switch pressed.\n");
|
||||
break;
|
||||
default:
|
||||
shell_fprintf_error(sh, "Stepper: Unknown signal received.\n");
|
||||
break;
|
||||
}
|
||||
|
||||
k_poll_signal_reset(&stepper_signal);
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
static int start_polling(const struct shell *sh)
|
||||
{
|
||||
k_tid_t tid;
|
||||
|
||||
if (poll_thread_started) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
k_poll_signal_init(&stepper_signal);
|
||||
tid = k_thread_create(&poll_thread, poll_thread_stack,
|
||||
K_KERNEL_STACK_SIZEOF(poll_thread_stack), stepper_poll_thread,
|
||||
(void *)sh, NULL, NULL, CONFIG_STEPPER_SHELL_THREAD_PRIORITY, 0,
|
||||
K_NO_WAIT);
|
||||
if (!tid) {
|
||||
shell_error(sh, "Cannot start poll thread");
|
||||
return -ENOEXEC;
|
||||
}
|
||||
|
||||
k_thread_name_set(tid, "stepper_shell");
|
||||
k_thread_start(tid);
|
||||
poll_thread_started = true;
|
||||
return 0;
|
||||
}
|
||||
|
||||
#endif /* CONFIG_STEPPER_SHELL_ASYNC */
|
||||
|
||||
SHELL_STATIC_SUBCMD_SET_CREATE(
|
||||
stepper_cmds,
|
||||
SHELL_CMD_ARG(enable, &dsub_pos_stepper_motor_name, "<device> <on/off>", cmd_stepper_enable,
|
||||
|
|
|
|||
|
|
@ -16,30 +16,32 @@ extern "C" {
|
|||
|
||||
DECLARE_FAKE_VALUE_FUNC(int, fake_stepper_enable, const struct device *, const bool);
|
||||
|
||||
DECLARE_FAKE_VALUE_FUNC(int, fake_stepper_move, const struct device *, const int32_t,
|
||||
struct k_poll_signal *);
|
||||
DECLARE_FAKE_VALUE_FUNC(int, fake_stepper_move, const struct device *, const int32_t);
|
||||
|
||||
DECLARE_FAKE_VALUE_FUNC(int, fake_stepper_set_max_velocity, const struct device *, const uint32_t);
|
||||
|
||||
DECLARE_FAKE_VALUE_FUNC(int, fake_stepper_set_micro_step_res, const struct device *,
|
||||
const enum micro_step_resolution);
|
||||
const enum stepper_micro_step_resolution);
|
||||
|
||||
DECLARE_FAKE_VALUE_FUNC(int, fake_stepper_get_micro_step_res, const struct device *,
|
||||
enum micro_step_resolution *);
|
||||
enum stepper_micro_step_resolution *);
|
||||
|
||||
DECLARE_FAKE_VALUE_FUNC(int, fake_stepper_set_actual_position, const struct device *,
|
||||
const int32_t);
|
||||
|
||||
DECLARE_FAKE_VALUE_FUNC(int, fake_stepper_get_actual_position, const struct device *, int32_t *);
|
||||
|
||||
DECLARE_FAKE_VALUE_FUNC(int, fake_stepper_set_target_position, const struct device *, const int32_t,
|
||||
struct k_poll_signal *);
|
||||
DECLARE_FAKE_VALUE_FUNC(int, fake_stepper_set_target_position, const struct device *,
|
||||
const int32_t);
|
||||
|
||||
DECLARE_FAKE_VALUE_FUNC(int, fake_stepper_is_moving, const struct device *, bool *);
|
||||
|
||||
DECLARE_FAKE_VALUE_FUNC(int, fake_stepper_enable_constant_velocity_mode, const struct device *,
|
||||
const enum stepper_direction, const uint32_t);
|
||||
|
||||
DECLARE_FAKE_VALUE_FUNC(int, fake_stepper_set_event_callback, const struct device *,
|
||||
stepper_event_callback_t, void *);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
|
|
|||
Loading…
Reference in a new issue