aboutsummaryrefslogtreecommitdiffstats
path: root/src
diff options
context:
space:
mode:
authorKevin O'Connor <kevin@koconnor.net>2025-05-07 17:47:22 -0400
committerKevin O'Connor <kevin@koconnor.net>2025-05-09 09:52:05 -0400
commitefabe63357b66addcf2ded42a5e601549e058c8a (patch)
treec5dcd7981bd73755a8ae6651b20403781949f5fe /src
parent1dc9aa8e192593a0cbc0e3de9376aa4877d9d947 (diff)
downloadkutter-efabe63357b66addcf2ded42a5e601549e058c8a.tar.gz
kutter-efabe63357b66addcf2ded42a5e601549e058c8a.tar.xz
kutter-efabe63357b66addcf2ded42a5e601549e058c8a.zip
stepper: Move timer checks from stepper_event_full() to stepper_load_next()
This simplifies the stepper_event_full() and makes it easier to implement more complex checks. Signed-off-by: Kevin O'Connor <kevin@koconnor.net>
Diffstat (limited to 'src')
-rw-r--r--src/stepper.c26
1 files changed, 16 insertions, 10 deletions
diff --git a/src/stepper.c b/src/stepper.c
index 7935c139..84655fe9 100644
--- a/src/stepper.c
+++ b/src/stepper.c
@@ -96,10 +96,19 @@ stepper_load_next(struct stepper *s)
} else {
// Using fully scheduled stepper_event_full() code (the scheduler
// may be called twice for each step)
+ uint_fast8_t was_active = !!s->count;
+ uint32_t min_next_time = s->time.waketime;
s->next_step_time += move_interval;
s->time.waketime = s->next_step_time;
s->count = (s->flags & SF_SINGLE_SCHED ? move_count
: (uint32_t)move_count * 2);
+ if (was_active && timer_is_before(s->next_step_time, min_next_time)) {
+ // Actively stepping and next step event close to the last unstep
+ int32_t diff = s->next_step_time - min_next_time;
+ if (diff < (int32_t)-timer_from_us(1000))
+ shutdown("Stepper too far in past");
+ s->time.waketime = min_next_time;
+ }
}
// Set new direction (if needed)
@@ -163,27 +172,24 @@ stepper_event_full(struct timer *t)
gpio_out_toggle_noirq(s->step_pin);
uint32_t curtime = timer_read_time();
uint32_t min_next_time = curtime + s->step_pulse_ticks;
- s->count--;
- if (likely(s->count & 1 && !(s->flags & SF_SINGLE_SCHED)))
+ uint32_t count = s->count - 1;
+ if (likely(count & 1 && !(s->flags & SF_SINGLE_SCHED)))
// Schedule unstep event
goto reschedule_min;
- if (likely(s->count)) {
+ if (likely(count)) {
s->next_step_time += s->interval;
s->interval += s->add;
if (unlikely(timer_is_before(s->next_step_time, min_next_time)))
// The next step event is too close - push it back
goto reschedule_min;
+ s->count = count;
s->time.waketime = s->next_step_time;
return SF_RESCHEDULE;
}
- uint_fast8_t ret = stepper_load_next(s);
- if (ret == SF_DONE || !timer_is_before(s->time.waketime, min_next_time))
- return ret;
- // Next step event is too close to the last unstep
- int32_t diff = s->time.waketime - min_next_time;
- if (diff < (int32_t)-timer_from_us(1000))
- shutdown("Stepper too far in past");
+ s->time.waketime = min_next_time;
+ return stepper_load_next(s);
reschedule_min:
+ s->count = count;
s->time.waketime = min_next_time;
return SF_RESCHEDULE;
}