stepper: Implement active callbacks via motion_queuing.register_flush_callback()

Use the existing register_flush_callback() system to implement motor
activity checking.  This simplifies the generate_steps() code.

Signed-off-by: Kevin O'Connor <kevin@koconnor.net>
This commit is contained in:
Kevin O'Connor 2025-08-05 14:50:36 -04:00
parent b5e573957c
commit c454e88d9a
4 changed files with 29 additions and 14 deletions

View File

@ -50,10 +50,15 @@ class PrinterMotionQueuing:
self.steppers.append(stepper) self.steppers.append(stepper)
def register_flush_callback(self, callback): def register_flush_callback(self, callback):
self.flush_callbacks.append(callback) self.flush_callbacks.append(callback)
def unregister_flush_callback(self, callback):
if callback in self.flush_callbacks:
fcbs = list(self.flush_callbacks)
fcbs.remove(callback)
self.flush_callbacks = fcbs
def flush_motion_queues(self, must_flush_time, max_step_gen_time): def flush_motion_queues(self, must_flush_time, max_step_gen_time):
# Invoke flush callbacks (if any) # Invoke flush callbacks (if any)
for cb in self.flush_callbacks: for cb in self.flush_callbacks:
cb(must_flush_time) cb(must_flush_time, max_step_gen_time)
# Generate itersolve steps # Generate itersolve steps
for stepper in self.steppers: for stepper in self.steppers:
stepper.generate_steps(max_step_gen_time) stepper.generate_steps(max_step_gen_time)

View File

@ -25,12 +25,12 @@ class GCodeRequestQueue:
printer.register_event_handler("klippy:connect", self._handle_connect) printer.register_event_handler("klippy:connect", self._handle_connect)
def _handle_connect(self): def _handle_connect(self):
self.toolhead = self.printer.lookup_object('toolhead') self.toolhead = self.printer.lookup_object('toolhead')
def _flush_notification(self, print_time): def _flush_notification(self, must_flush_time, max_step_gen_time):
min_sched_time = self.mcu.min_schedule_time() min_sched_time = self.mcu.min_schedule_time()
rqueue = self.rqueue rqueue = self.rqueue
while rqueue: while rqueue:
next_time = max(rqueue[0][0], self.next_min_flush_time) next_time = max(rqueue[0][0], self.next_min_flush_time)
if next_time > print_time: if next_time > must_flush_time:
return return
# Skip requests that have been overridden with a following request # Skip requests that have been overridden with a following request
pos = 0 pos = 0

View File

@ -124,8 +124,8 @@ class MCU_queued_pwm:
value = 1. - value value = 1. - value
v = int(max(0., min(1., value)) * self._pwm_max + 0.5) v = int(max(0., min(1., value)) * self._pwm_max + 0.5)
self._send_update(clock, v) self._send_update(clock, v)
def _flush_notification(self, print_time): def _flush_notification(self, must_flush_time, max_step_gen_time):
clock = self._mcu.print_time_to_clock(print_time) clock = self._mcu.print_time_to_clock(must_flush_time)
if self._last_value != self._default_value: if self._last_value != self._default_value:
while clock >= self._last_clock + self._duration_ticks: while clock >= self._last_clock + self._duration_ticks:
self._send_update(self._last_clock + self._duration_ticks, self._send_update(self._last_clock + self._duration_ticks,

View File

@ -235,16 +235,26 @@ class MCU_stepper:
return old_tq return old_tq
def add_active_callback(self, cb): def add_active_callback(self, cb):
self._active_callbacks.append(cb) self._active_callbacks.append(cb)
def generate_steps(self, flush_time): if len(self._active_callbacks) == 1:
# Check for activity if necessary printer = self._mcu.get_printer()
if self._active_callbacks: motion_queuing = printer.lookup_object('motion_queuing')
motion_queuing.register_flush_callback(self._check_active)
def _check_active(self, must_flush_time, max_step_gen_time):
sk = self._stepper_kinematics sk = self._stepper_kinematics
ret = self._itersolve_check_active(sk, flush_time) ret = self._itersolve_check_active(sk, max_step_gen_time)
if ret: if not ret:
# Stepper motor still not active
return
# Motor is active, disable future checking
printer = self._mcu.get_printer()
motion_queuing = printer.lookup_object('motion_queuing')
motion_queuing.unregister_flush_callback(self._check_active)
cbs = self._active_callbacks cbs = self._active_callbacks
self._active_callbacks = [] self._active_callbacks = []
# Invoke callbacks
for cb in cbs: for cb in cbs:
cb(ret) cb(ret)
def generate_steps(self, flush_time):
# Generate steps # Generate steps
sk = self._stepper_kinematics sk = self._stepper_kinematics
ret = self._itersolve_generate_steps(sk, flush_time) ret = self._itersolve_generate_steps(sk, flush_time)