Skip to content

Commit 9eda3d9

Browse files
committed
drivers: stepper: step_dir: Adjust toggeling speed of step pin
Changes the timing source to perform the stepping in half of the given frequency to space out the toggeling of the step pin more. This fixes misstepping for configurations where the speed of successive toggeling exceeds what the stepper driver can handle. Fixes #87698. Signed-off-by: Fabian Blatz <[email protected]>
1 parent ce4240f commit 9eda3d9

File tree

4 files changed

+25
-9
lines changed

4 files changed

+25
-9
lines changed

drivers/stepper/step_dir/step_dir_stepper_common.c

+12-6
Original file line numberDiff line numberDiff line change
@@ -36,12 +36,10 @@ static inline int step_dir_stepper_perform_step(const struct device *dev)
3636
return ret;
3737
}
3838

39-
if (!config->dual_edge) {
40-
ret = gpio_pin_toggle_dt(&config->step_pin);
41-
if (ret < 0) {
42-
LOG_ERR("Failed to toggle step pin: %d", ret);
43-
return ret;
44-
}
39+
data->toggle_count++;
40+
41+
if (!config->dual_edge && data->toggle_count % 2 != 0) {
42+
return 0;
4543
}
4644

4745
if (data->direction == STEPPER_DIRECTION_POSITIVE) {
@@ -332,6 +330,7 @@ int step_dir_stepper_common_run(const struct device *dev, const enum stepper_dir
332330
int step_dir_stepper_common_stop(const struct device *dev)
333331
{
334332
const struct step_dir_stepper_common_config *config = dev->config;
333+
struct step_dir_stepper_common_data *data = dev->data;
335334
int ret;
336335

337336
ret = config->timing_source->stop(dev);
@@ -340,6 +339,13 @@ int step_dir_stepper_common_stop(const struct device *dev)
340339
return ret;
341340
}
342341

342+
ret = gpio_pin_set_dt(&config->step_pin, 0);
343+
if (ret < 0) {
344+
LOG_ERR("Failed to set step pin: %d", ret);
345+
return ret;
346+
}
347+
data->toggle_count = 0;
348+
343349
stepper_trigger_callback(dev, STEPPER_EVENT_STOPPED);
344350
return 0;
345351
}

drivers/stepper/step_dir/step_dir_stepper_common.h

+1
Original file line numberDiff line numberDiff line change
@@ -74,6 +74,7 @@ struct step_dir_stepper_common_data {
7474
int32_t actual_position;
7575
uint64_t microstep_interval_ns;
7676
int32_t step_count;
77+
uint8_t toggle_count;
7778
stepper_event_callback_t callback;
7879
void *event_cb_user_data;
7980

drivers/stepper/step_dir/step_dir_stepper_counter_timing.c

+6-2
Original file line numberDiff line numberDiff line change
@@ -23,13 +23,17 @@ int step_counter_timing_source_update(const struct device *dev,
2323
const struct step_dir_stepper_common_config *config = dev->config;
2424
struct step_dir_stepper_common_data *data = dev->data;
2525
int ret;
26+
uint64_t toggle_freq = counter_get_frequency(config->counter) * microstep_interval_ns;
2627

2728
if (microstep_interval_ns == 0) {
2829
return -EINVAL;
2930
}
3031

31-
data->counter_top_cfg.ticks = DIV_ROUND_UP(
32-
counter_get_frequency(config->counter) * microstep_interval_ns, NSEC_PER_SEC);
32+
if (config->dual_edge) {
33+
data->counter_top_cfg.ticks = DIV_ROUND_UP(toggle_freq, NSEC_PER_SEC);
34+
} else {
35+
data->counter_top_cfg.ticks = DIV_ROUND_UP(toggle_freq / 2, NSEC_PER_SEC);
36+
}
3337

3438
/* Lock interrupts while modifying counter settings */
3539
int key = irq_lock();

drivers/stepper/step_dir/step_dir_stepper_work_timing.c

+6-1
Original file line numberDiff line numberDiff line change
@@ -9,12 +9,17 @@
99
static k_timeout_t stepper_movement_delay(const struct device *dev)
1010
{
1111
const struct step_dir_stepper_common_data *data = dev->data;
12+
const struct step_dir_stepper_common_config *config = dev->config;
1213

1314
if (data->microstep_interval_ns == 0) {
1415
return K_FOREVER;
1516
}
1617

17-
return K_NSEC(data->microstep_interval_ns);
18+
if (config->dual_edge) {
19+
return K_NSEC(data->microstep_interval_ns);
20+
} else {
21+
return K_NSEC(data->microstep_interval_ns / 2);
22+
}
1823
}
1924

2025
static void stepper_work_step_handler(struct k_work *work)

0 commit comments

Comments
 (0)