diff --git a/klippy/mcu.py b/klippy/mcu.py index 530da118..ec64c276 100644 --- a/klippy/mcu.py +++ b/klippy/mcu.py @@ -151,10 +151,10 @@ class MCU_stepper: class MCU_endstop: error = error RETRY_QUERY = 1.000 - def __init__(self, mcu, pin, stepper): + def __init__(self, mcu, pin): self._mcu = mcu self._oid = mcu.create_oid(self) - self._stepper = stepper + self._steppers = [] self._pin, self._pullup, self._invert = parse_pin_extras( pin, can_pullup=True) self._cmd_queue = mcu.alloc_command_queue() @@ -164,18 +164,27 @@ class MCU_endstop: self._next_query_clock = self._home_timeout_clock = 0 self._retry_query_ticks = 0 self._last_state = {} + mcu.add_init_callback(self._init_callback) self.print_to_mcu_time = mcu.print_to_mcu_time + def add_stepper(self, stepper): + self._steppers.append(stepper) def build_config(self): self._mcu_freq = self._mcu.get_mcu_freq() self._mcu.add_config_cmd( - "config_end_stop oid=%d pin=%s pull_up=%d stepper_oid=%d" % ( - self._oid, self._pin, self._pullup, self._stepper.get_oid())) + "config_end_stop oid=%d pin=%s pull_up=%d stepper_count=%d" % ( + self._oid, self._pin, self._pullup, len(self._steppers))) self._retry_query_ticks = int(self._mcu_freq * self.RETRY_QUERY) self._home_cmd = self._mcu.lookup_command( "end_stop_home oid=%c clock=%u rest_ticks=%u pin_value=%c") self._query_cmd = self._mcu.lookup_command("end_stop_query oid=%c") self._mcu.register_msg(self._handle_end_stop_state, "end_stop_state" , self._oid) + def _init_callback(self): + set_cmd = self._mcu.lookup_command( + "end_stop_set_stepper oid=%c pos=%c stepper_oid=%c") + for i, s in enumerate(self._steppers): + msg = set_cmd.encode(self._oid, i, s.get_oid()) + self._mcu.send(msg, cq=self._cmd_queue) def home_start(self, mcu_time, rest_time): clock = int(mcu_time * self._mcu_freq) rest_ticks = int(rest_time * self._mcu_freq) @@ -185,9 +194,11 @@ class MCU_endstop: msg = self._home_cmd.encode( self._oid, clock, rest_ticks, 1 ^ self._invert) self._mcu.send(msg, reqclock=clock, cq=self._cmd_queue) - self._stepper.note_homing_start(clock) + for s in self._steppers: + s.note_homing_start(clock) def home_finalize(self, mcu_time): - self._stepper.note_homing_finalized() + for s in self._steppers: + s.note_homing_finalized() self._home_timeout_clock = int(mcu_time * self._mcu_freq) def home_wait(self): eventtime = self._mcu.monotonic() @@ -205,7 +216,8 @@ class MCU_endstop: if not self._homing: return False if not self._last_state.get('homing', 0): - self._stepper.note_homing_triggered() + for s in self._steppers: + s.note_homing_triggered() self._homing = False return False if (self._mcu.serial.get_clock(last_sent_time) @@ -558,8 +570,8 @@ class MCU: # Wrappers for mcu object creation def create_stepper(self, step_pin, dir_pin): return MCU_stepper(self, step_pin, dir_pin) - def create_endstop(self, pin, stepper): - return MCU_endstop(self, pin, stepper) + def create_endstop(self, pin): + return MCU_endstop(self, pin) def create_digital_out(self, pin, max_duration=2.): return MCU_digital_out(self, pin, max_duration) def create_pwm(self, pin, cycle_time, hard_cycle_ticks=0, max_duration=2.): diff --git a/klippy/stepper.py b/klippy/stepper.py index e362dee4..eb8c2400 100644 --- a/klippy/stepper.py +++ b/klippy/stepper.py @@ -47,7 +47,8 @@ class PrinterStepper: if enable_pin is not None: self.mcu_enable = mcu.create_digital_out(enable_pin, 0) if endstop_pin is not None: - self.mcu_endstop = mcu.create_endstop(endstop_pin, self.mcu_stepper) + self.mcu_endstop = mcu.create_endstop(endstop_pin) + self.mcu_endstop.add_stepper(self.mcu_stepper) self.position_min = config.getfloat('position_min', 0.) self.position_endstop = config.getfloat('position_endstop') self.position_max = config.getfloat('position_max', 0.) diff --git a/src/endstop.c b/src/endstop.c index a504de92..91a278cc 100644 --- a/src/endstop.c +++ b/src/endstop.c @@ -14,13 +14,23 @@ struct end_stop { struct timer time; uint32_t rest_time; - struct stepper *stepper; struct gpio_in pin; - uint8_t flags; + uint8_t flags, stepper_count; + struct stepper *steppers[0]; }; enum { ESF_PIN_HIGH=1<<0, ESF_HOMING=1<<1, ESF_REPORT=1<<2 }; +static void noinline +stop_steppers(struct end_stop *e) +{ + e->flags = ESF_REPORT; + uint8_t count = e->stepper_count; + while (count--) + if (e->steppers[count]) + stepper_stop(e->steppers[count]); +} + // Timer callback for an end stop static uint_fast8_t end_stop_event(struct timer *t) @@ -32,23 +42,35 @@ end_stop_event(struct timer *t) e->time.waketime += e->rest_time; return SF_RESCHEDULE; } - // Stop stepper - e->flags = ESF_REPORT; - stepper_stop(e->stepper); + stop_steppers(e); return SF_DONE; } void command_config_end_stop(uint32_t *args) { - struct end_stop *e = oid_alloc(args[0], command_config_end_stop, sizeof(*e)); - struct stepper *s = stepper_oid_lookup(args[3]); + uint8_t stepper_count = args[3]; + struct end_stop *e = oid_alloc( + args[0], command_config_end_stop + , sizeof(*e) + sizeof(e->steppers[0]) * stepper_count); e->time.func = end_stop_event; - e->stepper = s; e->pin = gpio_in_setup(args[1], args[2]); + e->stepper_count = stepper_count; } DECL_COMMAND(command_config_end_stop, - "config_end_stop oid=%c pin=%c pull_up=%c stepper_oid=%c"); + "config_end_stop oid=%c pin=%c pull_up=%c stepper_count=%c"); + +void +command_end_stop_set_stepper(uint32_t *args) +{ + struct end_stop *e = oid_lookup(args[0], command_config_end_stop); + uint8_t pos = args[1]; + if (pos >= e->stepper_count) + shutdown("Set stepper past maximum stepper count"); + e->steppers[pos] = stepper_oid_lookup(args[2]); +} +DECL_COMMAND(command_end_stop_set_stepper, + "end_stop_set_stepper oid=%c pos=%c stepper_oid=%c"); // Home an axis void