endstop: Support halting more than one stepper on trigger
Extend the endstop code so that more than one stepper can be halted during endstop homing. Some kinematic setups (eg, corexy) require an endstop to support this. Signed-off-by: Kevin O'Connor <kevin@koconnor.net>
This commit is contained in:
parent
fff73c7735
commit
57f279677f
|
@ -151,10 +151,10 @@ class MCU_stepper:
|
||||||
class MCU_endstop:
|
class MCU_endstop:
|
||||||
error = error
|
error = error
|
||||||
RETRY_QUERY = 1.000
|
RETRY_QUERY = 1.000
|
||||||
def __init__(self, mcu, pin, stepper):
|
def __init__(self, mcu, pin):
|
||||||
self._mcu = mcu
|
self._mcu = mcu
|
||||||
self._oid = mcu.create_oid(self)
|
self._oid = mcu.create_oid(self)
|
||||||
self._stepper = stepper
|
self._steppers = []
|
||||||
self._pin, self._pullup, self._invert = parse_pin_extras(
|
self._pin, self._pullup, self._invert = parse_pin_extras(
|
||||||
pin, can_pullup=True)
|
pin, can_pullup=True)
|
||||||
self._cmd_queue = mcu.alloc_command_queue()
|
self._cmd_queue = mcu.alloc_command_queue()
|
||||||
|
@ -164,18 +164,27 @@ class MCU_endstop:
|
||||||
self._next_query_clock = self._home_timeout_clock = 0
|
self._next_query_clock = self._home_timeout_clock = 0
|
||||||
self._retry_query_ticks = 0
|
self._retry_query_ticks = 0
|
||||||
self._last_state = {}
|
self._last_state = {}
|
||||||
|
mcu.add_init_callback(self._init_callback)
|
||||||
self.print_to_mcu_time = mcu.print_to_mcu_time
|
self.print_to_mcu_time = mcu.print_to_mcu_time
|
||||||
|
def add_stepper(self, stepper):
|
||||||
|
self._steppers.append(stepper)
|
||||||
def build_config(self):
|
def build_config(self):
|
||||||
self._mcu_freq = self._mcu.get_mcu_freq()
|
self._mcu_freq = self._mcu.get_mcu_freq()
|
||||||
self._mcu.add_config_cmd(
|
self._mcu.add_config_cmd(
|
||||||
"config_end_stop oid=%d pin=%s pull_up=%d stepper_oid=%d" % (
|
"config_end_stop oid=%d pin=%s pull_up=%d stepper_count=%d" % (
|
||||||
self._oid, self._pin, self._pullup, self._stepper.get_oid()))
|
self._oid, self._pin, self._pullup, len(self._steppers)))
|
||||||
self._retry_query_ticks = int(self._mcu_freq * self.RETRY_QUERY)
|
self._retry_query_ticks = int(self._mcu_freq * self.RETRY_QUERY)
|
||||||
self._home_cmd = self._mcu.lookup_command(
|
self._home_cmd = self._mcu.lookup_command(
|
||||||
"end_stop_home oid=%c clock=%u rest_ticks=%u pin_value=%c")
|
"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._query_cmd = self._mcu.lookup_command("end_stop_query oid=%c")
|
||||||
self._mcu.register_msg(self._handle_end_stop_state, "end_stop_state"
|
self._mcu.register_msg(self._handle_end_stop_state, "end_stop_state"
|
||||||
, self._oid)
|
, 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):
|
def home_start(self, mcu_time, rest_time):
|
||||||
clock = int(mcu_time * self._mcu_freq)
|
clock = int(mcu_time * self._mcu_freq)
|
||||||
rest_ticks = int(rest_time * self._mcu_freq)
|
rest_ticks = int(rest_time * self._mcu_freq)
|
||||||
|
@ -185,9 +194,11 @@ class MCU_endstop:
|
||||||
msg = self._home_cmd.encode(
|
msg = self._home_cmd.encode(
|
||||||
self._oid, clock, rest_ticks, 1 ^ self._invert)
|
self._oid, clock, rest_ticks, 1 ^ self._invert)
|
||||||
self._mcu.send(msg, reqclock=clock, cq=self._cmd_queue)
|
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):
|
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)
|
self._home_timeout_clock = int(mcu_time * self._mcu_freq)
|
||||||
def home_wait(self):
|
def home_wait(self):
|
||||||
eventtime = self._mcu.monotonic()
|
eventtime = self._mcu.monotonic()
|
||||||
|
@ -205,7 +216,8 @@ class MCU_endstop:
|
||||||
if not self._homing:
|
if not self._homing:
|
||||||
return False
|
return False
|
||||||
if not self._last_state.get('homing', 0):
|
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
|
self._homing = False
|
||||||
return False
|
return False
|
||||||
if (self._mcu.serial.get_clock(last_sent_time)
|
if (self._mcu.serial.get_clock(last_sent_time)
|
||||||
|
@ -558,8 +570,8 @@ class MCU:
|
||||||
# Wrappers for mcu object creation
|
# Wrappers for mcu object creation
|
||||||
def create_stepper(self, step_pin, dir_pin):
|
def create_stepper(self, step_pin, dir_pin):
|
||||||
return MCU_stepper(self, step_pin, dir_pin)
|
return MCU_stepper(self, step_pin, dir_pin)
|
||||||
def create_endstop(self, pin, stepper):
|
def create_endstop(self, pin):
|
||||||
return MCU_endstop(self, pin, stepper)
|
return MCU_endstop(self, pin)
|
||||||
def create_digital_out(self, pin, max_duration=2.):
|
def create_digital_out(self, pin, max_duration=2.):
|
||||||
return MCU_digital_out(self, pin, max_duration)
|
return MCU_digital_out(self, pin, max_duration)
|
||||||
def create_pwm(self, pin, cycle_time, hard_cycle_ticks=0, max_duration=2.):
|
def create_pwm(self, pin, cycle_time, hard_cycle_ticks=0, max_duration=2.):
|
||||||
|
|
|
@ -47,7 +47,8 @@ class PrinterStepper:
|
||||||
if enable_pin is not None:
|
if enable_pin is not None:
|
||||||
self.mcu_enable = mcu.create_digital_out(enable_pin, 0)
|
self.mcu_enable = mcu.create_digital_out(enable_pin, 0)
|
||||||
if endstop_pin is not None:
|
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_min = config.getfloat('position_min', 0.)
|
||||||
self.position_endstop = config.getfloat('position_endstop')
|
self.position_endstop = config.getfloat('position_endstop')
|
||||||
self.position_max = config.getfloat('position_max', 0.)
|
self.position_max = config.getfloat('position_max', 0.)
|
||||||
|
|
|
@ -14,13 +14,23 @@
|
||||||
struct end_stop {
|
struct end_stop {
|
||||||
struct timer time;
|
struct timer time;
|
||||||
uint32_t rest_time;
|
uint32_t rest_time;
|
||||||
struct stepper *stepper;
|
|
||||||
struct gpio_in pin;
|
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 };
|
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
|
// Timer callback for an end stop
|
||||||
static uint_fast8_t
|
static uint_fast8_t
|
||||||
end_stop_event(struct timer *t)
|
end_stop_event(struct timer *t)
|
||||||
|
@ -32,23 +42,35 @@ end_stop_event(struct timer *t)
|
||||||
e->time.waketime += e->rest_time;
|
e->time.waketime += e->rest_time;
|
||||||
return SF_RESCHEDULE;
|
return SF_RESCHEDULE;
|
||||||
}
|
}
|
||||||
// Stop stepper
|
stop_steppers(e);
|
||||||
e->flags = ESF_REPORT;
|
|
||||||
stepper_stop(e->stepper);
|
|
||||||
return SF_DONE;
|
return SF_DONE;
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
command_config_end_stop(uint32_t *args)
|
command_config_end_stop(uint32_t *args)
|
||||||
{
|
{
|
||||||
struct end_stop *e = oid_alloc(args[0], command_config_end_stop, sizeof(*e));
|
uint8_t stepper_count = args[3];
|
||||||
struct stepper *s = stepper_oid_lookup(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->time.func = end_stop_event;
|
||||||
e->stepper = s;
|
|
||||||
e->pin = gpio_in_setup(args[1], args[2]);
|
e->pin = gpio_in_setup(args[1], args[2]);
|
||||||
|
e->stepper_count = stepper_count;
|
||||||
}
|
}
|
||||||
DECL_COMMAND(command_config_end_stop,
|
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
|
// Home an axis
|
||||||
void
|
void
|
||||||
|
|
Loading…
Reference in New Issue