drivers: stepper: refactor gpio stepper driver

This commit refactors gpio stepper driver

Signed-off-by: Jilay Pandya <jilay.pandya@outlook.com>
This commit is contained in:
Jilay Pandya 2024-08-30 10:31:02 +02:00 committed by Carles Cufí
commit fda97de253

View file

@ -19,14 +19,14 @@ LOG_MODULE_REGISTER(gpio_stepper_motor_controller, CONFIG_STEPPER_LOG_LEVEL);
static const uint8_t static const uint8_t
half_step_lookup_table[NUM_CONTROL_PINS * MAX_MICRO_STEP_RES][NUM_CONTROL_PINS] = { half_step_lookup_table[NUM_CONTROL_PINS * MAX_MICRO_STEP_RES][NUM_CONTROL_PINS] = {
{1, 1, 0, 0}, {0, 1, 0, 0}, {0, 1, 1, 0}, {0, 0, 1, 0}, {1u, 1u, 0u, 0u}, {0u, 1u, 0u, 0u}, {0u, 1u, 1u, 0u}, {0u, 0u, 1u, 0u},
{0, 0, 1, 1}, {0, 0, 0, 1}, {1, 0, 0, 1}, {1, 0, 0, 0}}; {0u, 0u, 1u, 1u}, {0u, 0u, 0u, 1u}, {1u, 0u, 0u, 1u}, {1u, 0u, 0u, 0u}};
struct gpio_stepper_motor_controller_config { struct gpio_stepper_config {
const struct gpio_dt_spec *control_pins; const struct gpio_dt_spec *control_pins;
}; };
struct gpio_stepper_motor_controller_data { struct gpio_stepper_data {
const struct device *dev; const struct device *dev;
struct k_spinlock lock; struct k_spinlock lock;
enum stepper_direction direction; enum stepper_direction direction;
@ -42,19 +42,19 @@ struct gpio_stepper_motor_controller_data {
static int stepper_motor_set_coil_charge(const struct device *dev) static int stepper_motor_set_coil_charge(const struct device *dev)
{ {
struct gpio_stepper_motor_controller_data *data = dev->data; struct gpio_stepper_data *data = dev->data;
const struct gpio_stepper_motor_controller_config *config = dev->config; const struct gpio_stepper_config *config = dev->config;
for (int i = 0; i < NUM_CONTROL_PINS; i++) { for (int i = 0; i < NUM_CONTROL_PINS; i++) {
gpio_pin_set_dt(&config->control_pins[i], (void)gpio_pin_set_dt(&config->control_pins[i],
half_step_lookup_table[data->coil_charge][i]); half_step_lookup_table[data->coil_charge][i]);
} }
return 0; return 0;
} }
static void update_coil_charge(const struct device *dev) static void update_coil_charge(const struct device *dev)
{ {
struct gpio_stepper_motor_controller_data *data = dev->data; struct gpio_stepper_data *data = dev->data;
if (data->direction == STEPPER_DIRECTION_POSITIVE) { if (data->direction == STEPPER_DIRECTION_POSITIVE) {
data->coil_charge = data->coil_charge == 0 data->coil_charge = data->coil_charge == 0
@ -70,22 +70,23 @@ static void update_coil_charge(const struct device *dev)
} }
} }
static void update_remaining_steps(struct gpio_stepper_motor_controller_data *data) static void update_remaining_steps(struct gpio_stepper_data *data)
{ {
if (data->step_count > 0) { if (data->step_count > 0) {
data->step_count--; data->step_count--;
k_work_reschedule(&data->stepper_dwork, K_USEC(data->delay_in_us)); (void)k_work_reschedule(&data->stepper_dwork, K_USEC(data->delay_in_us));
} else if (data->step_count < 0) { } else if (data->step_count < 0) {
data->step_count++; data->step_count++;
k_work_reschedule(&data->stepper_dwork, K_USEC(data->delay_in_us)); (void)k_work_reschedule(&data->stepper_dwork, K_USEC(data->delay_in_us));
} else { } else {
if (data->async_signal) { if (data->async_signal) {
k_poll_signal_raise(data->async_signal, STEPPER_SIGNAL_STEPS_COMPLETED); (void)k_poll_signal_raise(data->async_signal,
STEPPER_SIGNAL_STEPS_COMPLETED);
} }
} }
} }
static void update_direction_from_step_count(struct gpio_stepper_motor_controller_data *data) static void update_direction_from_step_count(struct gpio_stepper_data *data)
{ {
if (data->step_count > 0) { if (data->step_count > 0) {
data->direction = STEPPER_DIRECTION_POSITIVE; data->direction = STEPPER_DIRECTION_POSITIVE;
@ -98,10 +99,10 @@ static void update_direction_from_step_count(struct gpio_stepper_motor_controlle
static void position_mode_task(const struct device *dev) static void position_mode_task(const struct device *dev)
{ {
struct gpio_stepper_motor_controller_data *data = dev->data; struct gpio_stepper_data *data = dev->data;
if (data->step_count) { if (data->step_count) {
stepper_motor_set_coil_charge(dev); (void)stepper_motor_set_coil_charge(dev);
update_coil_charge(dev); update_coil_charge(dev);
} }
update_remaining_steps(dev->data); update_remaining_steps(dev->data);
@ -109,18 +110,18 @@ static void position_mode_task(const struct device *dev)
static void velocity_mode_task(const struct device *dev) static void velocity_mode_task(const struct device *dev)
{ {
struct gpio_stepper_motor_controller_data *data = dev->data; struct gpio_stepper_data *data = dev->data;
stepper_motor_set_coil_charge(dev); (void)stepper_motor_set_coil_charge(dev);
update_coil_charge(dev); update_coil_charge(dev);
k_work_reschedule(&data->stepper_dwork, K_USEC(data->delay_in_us)); (void)k_work_reschedule(&data->stepper_dwork, K_USEC(data->delay_in_us));
} }
static void stepper_work_step_handler(struct k_work *work) static void stepper_work_step_handler(struct k_work *work)
{ {
struct k_work_delayable *dwork = k_work_delayable_from_work(work); struct k_work_delayable *dwork = k_work_delayable_from_work(work);
struct gpio_stepper_motor_controller_data *data = struct gpio_stepper_data *data =
CONTAINER_OF(dwork, struct gpio_stepper_motor_controller_data, stepper_dwork); CONTAINER_OF(dwork, struct gpio_stepper_data, stepper_dwork);
K_SPINLOCK(&data->lock) { K_SPINLOCK(&data->lock) {
switch (data->run_mode) { switch (data->run_mode) {
@ -140,7 +141,7 @@ static void stepper_work_step_handler(struct k_work *work)
static int gpio_stepper_move(const struct device *dev, int32_t micro_steps, static int gpio_stepper_move(const struct device *dev, int32_t micro_steps,
struct k_poll_signal *async) struct k_poll_signal *async)
{ {
struct gpio_stepper_motor_controller_data *data = dev->data; struct gpio_stepper_data *data = dev->data;
if (data->delay_in_us == 0) { if (data->delay_in_us == 0) {
LOG_ERR("Velocity not set or invalid velocity set"); LOG_ERR("Velocity not set or invalid velocity set");
@ -154,14 +155,14 @@ static int gpio_stepper_move(const struct device *dev, int32_t micro_steps,
data->run_mode = STEPPER_POSITION_MODE; data->run_mode = STEPPER_POSITION_MODE;
data->step_count = micro_steps; data->step_count = micro_steps;
update_direction_from_step_count(data); update_direction_from_step_count(data);
k_work_reschedule(&data->stepper_dwork, K_NO_WAIT); (void)k_work_reschedule(&data->stepper_dwork, K_NO_WAIT);
} }
return 0; return 0;
} }
static int gpio_stepper_set_actual_position(const struct device *dev, int32_t position) static int gpio_stepper_set_actual_position(const struct device *dev, int32_t position)
{ {
struct gpio_stepper_motor_controller_data *data = dev->data; struct gpio_stepper_data *data = dev->data;
K_SPINLOCK(&data->lock) { K_SPINLOCK(&data->lock) {
data->actual_position = position; data->actual_position = position;
@ -171,7 +172,7 @@ static int gpio_stepper_set_actual_position(const struct device *dev, int32_t po
static int gpio_stepper_get_actual_position(const struct device *dev, int32_t *position) static int gpio_stepper_get_actual_position(const struct device *dev, int32_t *position)
{ {
struct gpio_stepper_motor_controller_data *data = dev->data; struct gpio_stepper_data *data = dev->data;
K_SPINLOCK(&data->lock) { K_SPINLOCK(&data->lock) {
*position = data->actual_position; *position = data->actual_position;
@ -182,7 +183,7 @@ static int gpio_stepper_get_actual_position(const struct device *dev, int32_t *p
static int gpio_stepper_set_target_position(const struct device *dev, int32_t position, static int gpio_stepper_set_target_position(const struct device *dev, int32_t position,
struct k_poll_signal *async) struct k_poll_signal *async)
{ {
struct gpio_stepper_motor_controller_data *data = dev->data; struct gpio_stepper_data *data = dev->data;
if (data->delay_in_us == 0) { if (data->delay_in_us == 0) {
LOG_ERR("Velocity not set or invalid velocity set"); LOG_ERR("Velocity not set or invalid velocity set");
@ -196,23 +197,23 @@ static int gpio_stepper_set_target_position(const struct device *dev, int32_t po
data->run_mode = STEPPER_POSITION_MODE; data->run_mode = STEPPER_POSITION_MODE;
data->step_count = position - data->actual_position; data->step_count = position - data->actual_position;
update_direction_from_step_count(data); update_direction_from_step_count(data);
k_work_reschedule(&data->stepper_dwork, K_NO_WAIT); (void)k_work_reschedule(&data->stepper_dwork, K_NO_WAIT);
} }
return 0; return 0;
} }
static int gpio_stepper_is_moving(const struct device *dev, bool *is_moving) static int gpio_stepper_is_moving(const struct device *dev, bool *is_moving)
{ {
struct gpio_stepper_motor_controller_data *data = dev->data; struct gpio_stepper_data *data = dev->data;
*is_moving = k_work_delayable_is_pending(&data->stepper_dwork); *is_moving = k_work_delayable_is_pending(&data->stepper_dwork);
LOG_DBG("Is Motor Moving %d", *is_moving); LOG_DBG("Motor is %s moving", *is_moving ? "" : "not");
return 0; return 0;
} }
static int gpio_stepper_set_max_velocity(const struct device *dev, uint32_t velocity) static int gpio_stepper_set_max_velocity(const struct device *dev, uint32_t velocity)
{ {
struct gpio_stepper_motor_controller_data *data = dev->data; struct gpio_stepper_data *data = dev->data;
if (velocity == 0) { if (velocity == 0) {
LOG_ERR("Velocity cannot be zero"); LOG_ERR("Velocity cannot be zero");
@ -235,16 +236,16 @@ static int gpio_stepper_enable_constant_velocity_mode(const struct device *dev,
const enum stepper_direction direction, const enum stepper_direction direction,
const uint32_t value) const uint32_t value)
{ {
struct gpio_stepper_motor_controller_data *data = dev->data; struct gpio_stepper_data *data = dev->data;
K_SPINLOCK(&data->lock) { K_SPINLOCK(&data->lock) {
data->run_mode = STEPPER_VELOCITY_MODE; data->run_mode = STEPPER_VELOCITY_MODE;
data->direction = direction; data->direction = direction;
if (value != 0) { if (value != 0) {
data->delay_in_us = USEC_PER_SEC / value; data->delay_in_us = USEC_PER_SEC / value;
k_work_reschedule(&data->stepper_dwork, K_NO_WAIT); (void)k_work_reschedule(&data->stepper_dwork, K_NO_WAIT);
} else { } else {
k_work_cancel_delayable(&data->stepper_dwork); (void)k_work_cancel_delayable(&data->stepper_dwork);
} }
} }
return 0; return 0;
@ -253,7 +254,7 @@ static int gpio_stepper_enable_constant_velocity_mode(const struct device *dev,
static int gpio_stepper_set_micro_step_res(const struct device *dev, static int gpio_stepper_set_micro_step_res(const struct device *dev,
enum micro_step_resolution micro_step_res) enum micro_step_resolution micro_step_res)
{ {
struct gpio_stepper_motor_controller_data *data = dev->data; struct gpio_stepper_data *data = dev->data;
K_SPINLOCK(&data->lock) { K_SPINLOCK(&data->lock) {
switch (micro_step_res) { switch (micro_step_res) {
@ -272,20 +273,20 @@ static int gpio_stepper_set_micro_step_res(const struct device *dev,
static int gpio_stepper_get_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 micro_step_resolution *micro_step_res)
{ {
struct gpio_stepper_motor_controller_data *data = dev->data; struct gpio_stepper_data *data = dev->data;
*micro_step_res = MAX_MICRO_STEP_RES >> (data->step_gap - 1); *micro_step_res = MAX_MICRO_STEP_RES >> (data->step_gap - 1);
return 0; return 0;
} }
static int gpio_stepper_enable(const struct device *dev, bool enable) static int gpio_stepper_enable(const struct device *dev, bool enable)
{ {
struct gpio_stepper_motor_controller_data *data = dev->data; struct gpio_stepper_data *data = dev->data;
K_SPINLOCK(&data->lock) { K_SPINLOCK(&data->lock) {
if (enable) { if (enable) {
k_work_reschedule(&data->stepper_dwork, K_NO_WAIT); (void)k_work_reschedule(&data->stepper_dwork, K_NO_WAIT);
} else { } else {
k_work_cancel_delayable(&data->stepper_dwork); (void)k_work_cancel_delayable(&data->stepper_dwork);
} }
} }
return 0; return 0;
@ -293,23 +294,22 @@ static int gpio_stepper_enable(const struct device *dev, bool enable)
static int gpio_stepper_motor_controller_init(const struct device *dev) static int gpio_stepper_motor_controller_init(const struct device *dev)
{ {
struct gpio_stepper_motor_controller_data *data = dev->data; struct gpio_stepper_data *data = dev->data;
const struct gpio_stepper_motor_controller_config *config = dev->config; const struct gpio_stepper_config *config = dev->config;
data->dev = dev; data->dev = dev;
LOG_DBG("Initializing %s gpio_stepper_motor_controller with %d pin", dev->name, LOG_DBG("Initializing %s gpio_stepper_motor_controller with %d pin", dev->name,
NUM_CONTROL_PINS); NUM_CONTROL_PINS);
for (uint8_t n_pin = 0; n_pin < NUM_CONTROL_PINS; n_pin++) { for (uint8_t n_pin = 0; n_pin < NUM_CONTROL_PINS; n_pin++) {
gpio_pin_configure_dt(&config->control_pins[n_pin], GPIO_OUTPUT_INACTIVE); (void)gpio_pin_configure_dt(&config->control_pins[n_pin], GPIO_OUTPUT_INACTIVE);
} }
k_work_init_delayable(&data->stepper_dwork, stepper_work_step_handler); k_work_init_delayable(&data->stepper_dwork, stepper_work_step_handler);
return 0; return 0;
} }
#define GPIO_STEPPER_DEVICE_DATA_DEFINE(child) \ #define GPIO_STEPPER_DEVICE_DATA_DEFINE(child) \
static struct gpio_stepper_motor_controller_data \ static struct gpio_stepper_data gpio_stepper_data_##child = { \
gpio_stepper_motor_controller_data_##child = { \ .step_gap = MAX_MICRO_STEP_RES >> (DT_PROP(child, micro_step_res) - 1), \
.step_gap = MAX_MICRO_STEP_RES >> (DT_PROP(child, micro_step_res) - 1), \
}; \ }; \
BUILD_ASSERT(DT_PROP(child, micro_step_res) <= STEPPER_MICRO_STEP_2, \ BUILD_ASSERT(DT_PROP(child, micro_step_res) <= STEPPER_MICRO_STEP_2, \
"gpio_stepper_controller driver supports up to 2 micro steps"); "gpio_stepper_controller driver supports up to 2 micro steps");
@ -321,9 +321,8 @@ static int gpio_stepper_motor_controller_init(const struct device *dev)
BUILD_ASSERT( \ BUILD_ASSERT( \
ARRAY_SIZE(gpio_stepper_motor_control_pins_##child) == 4, \ ARRAY_SIZE(gpio_stepper_motor_control_pins_##child) == 4, \
"gpio_stepper_controller driver currently supports only 4 wire configuration"); \ "gpio_stepper_controller driver currently supports only 4 wire configuration"); \
static const struct gpio_stepper_motor_controller_config \ static const struct gpio_stepper_config gpio_stepper_config_##child = { \
gpio_stepper_motor_controller_config_##child = { \ .control_pins = gpio_stepper_motor_control_pins_##child};
.control_pins = gpio_stepper_motor_control_pins_##child};
#define GPIO_STEPPER_API_DEFINE(child) \ #define GPIO_STEPPER_API_DEFINE(child) \
static const struct stepper_driver_api gpio_stepper_api_##child = { \ static const struct stepper_driver_api gpio_stepper_api_##child = { \
@ -340,8 +339,7 @@ static int gpio_stepper_motor_controller_init(const struct device *dev)
#define GPIO_STEPPER_DEVICE_DEFINE(child) \ #define GPIO_STEPPER_DEVICE_DEFINE(child) \
DEVICE_DT_DEFINE(child, gpio_stepper_motor_controller_init, NULL, \ DEVICE_DT_DEFINE(child, gpio_stepper_motor_controller_init, NULL, \
&gpio_stepper_motor_controller_data_##child, \ &gpio_stepper_data_##child, &gpio_stepper_config_##child, POST_KERNEL, \
&gpio_stepper_motor_controller_config_##child, POST_KERNEL, \
CONFIG_STEPPER_INIT_PRIORITY, &gpio_stepper_api_##child); CONFIG_STEPPER_INIT_PRIORITY, &gpio_stepper_api_##child);
#define GPIO_STEPPER_CONTROLLER_DEFINE(inst) \ #define GPIO_STEPPER_CONTROLLER_DEFINE(inst) \