From c454e88d9aec86b149e1e3fa9daa75944872e74a Mon Sep 17 00:00:00 2001 From: Kevin O'Connor Date: Tue, 5 Aug 2025 14:50:36 -0400 Subject: [PATCH] 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 --- klippy/extras/motion_queuing.py | 7 ++++++- klippy/extras/output_pin.py | 4 ++-- klippy/extras/pwm_tool.py | 4 ++-- klippy/stepper.py | 28 +++++++++++++++++++--------- 4 files changed, 29 insertions(+), 14 deletions(-) diff --git a/klippy/extras/motion_queuing.py b/klippy/extras/motion_queuing.py index 6fadbef1..06fa5a9b 100644 --- a/klippy/extras/motion_queuing.py +++ b/klippy/extras/motion_queuing.py @@ -50,10 +50,15 @@ class PrinterMotionQueuing: self.steppers.append(stepper) def register_flush_callback(self, 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): # Invoke flush callbacks (if any) for cb in self.flush_callbacks: - cb(must_flush_time) + cb(must_flush_time, max_step_gen_time) # Generate itersolve steps for stepper in self.steppers: stepper.generate_steps(max_step_gen_time) diff --git a/klippy/extras/output_pin.py b/klippy/extras/output_pin.py index 9eb8ea8b..63862d97 100644 --- a/klippy/extras/output_pin.py +++ b/klippy/extras/output_pin.py @@ -25,12 +25,12 @@ class GCodeRequestQueue: printer.register_event_handler("klippy:connect", self._handle_connect) def _handle_connect(self): 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() rqueue = self.rqueue while rqueue: next_time = max(rqueue[0][0], self.next_min_flush_time) - if next_time > print_time: + if next_time > must_flush_time: return # Skip requests that have been overridden with a following request pos = 0 diff --git a/klippy/extras/pwm_tool.py b/klippy/extras/pwm_tool.py index 69fc1a46..6d401c0b 100644 --- a/klippy/extras/pwm_tool.py +++ b/klippy/extras/pwm_tool.py @@ -124,8 +124,8 @@ class MCU_queued_pwm: value = 1. - value v = int(max(0., min(1., value)) * self._pwm_max + 0.5) self._send_update(clock, v) - def _flush_notification(self, print_time): - clock = self._mcu.print_time_to_clock(print_time) + def _flush_notification(self, must_flush_time, max_step_gen_time): + clock = self._mcu.print_time_to_clock(must_flush_time) if self._last_value != self._default_value: while clock >= self._last_clock + self._duration_ticks: self._send_update(self._last_clock + self._duration_ticks, diff --git a/klippy/stepper.py b/klippy/stepper.py index 6ce9130f..8e6a883d 100644 --- a/klippy/stepper.py +++ b/klippy/stepper.py @@ -235,16 +235,26 @@ class MCU_stepper: return old_tq def add_active_callback(self, cb): self._active_callbacks.append(cb) + if len(self._active_callbacks) == 1: + printer = self._mcu.get_printer() + 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 + ret = self._itersolve_check_active(sk, max_step_gen_time) + 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 + self._active_callbacks = [] + # Invoke callbacks + for cb in cbs: + cb(ret) def generate_steps(self, flush_time): - # Check for activity if necessary - if self._active_callbacks: - sk = self._stepper_kinematics - ret = self._itersolve_check_active(sk, flush_time) - if ret: - cbs = self._active_callbacks - self._active_callbacks = [] - for cb in cbs: - cb(ret) # Generate steps sk = self._stepper_kinematics ret = self._itersolve_generate_steps(sk, flush_time)