endstop: Eliminate end_stop_set_oversample command

Pass the sample_ticks and sample_count parameters directly in the
end_stop_home command instead.  This simplifies the code.

Also, simplify calculation of next wakeup time in
end_stop_oversample_event().

Signed-off-by: Kevin O'Connor <kevin@koconnor.net>
This commit is contained in:
Kevin O'Connor 2017-10-12 10:39:46 -04:00
parent 78ba7064a7
commit 3b9b4e4d6f
5 changed files with 32 additions and 47 deletions

View File

@ -255,13 +255,15 @@ Stepper commands
number of steps generated with dir=1 minus the total number of steps number of steps generated with dir=1 minus the total number of steps
generated with dir=0. generated with dir=0.
* `end_stop_home oid=%c clock=%u rest_ticks=%u pin_value=%c` : This * `end_stop_home oid=%c clock=%u sample_ticks=%u sample_count=%c
command is used during stepper "homing" operations. To use this rest_ticks=%u pin_value=%c` : This command is used during stepper
command a 'config_end_stop' command with the same 'oid' parameter "homing" operations. To use this command a 'config_end_stop' command
must have been issued during micro-controller configuration. When with the same 'oid' parameter must have been issued during
this command is invoked, the micro-controller will sample the micro-controller configuration. When this command is invoked, the
endstop pin every 'rest_ticks' clock ticks and check if it has a micro-controller will sample the endstop pin every 'rest_ticks'
value equal to 'pin_value'. If the value matches then the movement clock ticks and check if it has a value equal to 'pin_value'. If the
value matches (and it continues to match for 'sample_count'
additional samples spread 'sample_ticks' apart) then the movement
queue for the associated stepper will be cleared and the stepper queue for the associated stepper will be cleared and the stepper
will come to an immediate halt. The host uses this command to will come to an immediate halt. The host uses this command to
implement homing - the host instructs the endstop to sample for the implement homing - the host instructs the endstop to sample for the

View File

@ -6,6 +6,8 @@
import logging import logging
HOMING_DELAY = 0.250 HOMING_DELAY = 0.250
ENDSTOP_SAMPLE_TIME = .000015
ENDSTOP_SAMPLE_COUNT = 4
class Homing: class Homing:
def __init__(self, toolhead, changed_axes): def __init__(self, toolhead, changed_axes):
@ -36,7 +38,8 @@ class Homing:
print_time = self.toolhead.get_last_move_time() print_time = self.toolhead.get_last_move_time()
endstops = [] endstops = []
for s in steppers: for s in steppers:
s.mcu_endstop.home_start(print_time, s.step_dist / speed) s.mcu_endstop.home_start(print_time, ENDSTOP_SAMPLE_TIME,
ENDSTOP_SAMPLE_COUNT, s.step_dist / speed)
endstops.append((s, s.mcu_stepper.get_mcu_position())) endstops.append((s, s.mcu_stepper.get_mcu_position()))
self.toolhead.move(self._fill_coord(movepos), speed) self.toolhead.move(self._fill_coord(movepos), speed)
move_end_print_time = self.toolhead.get_last_move_time() move_end_print_time = self.toolhead.get_last_move_time()

View File

@ -137,8 +137,6 @@ class MCU_endstop:
self._pin = pin_params['pin'] self._pin = pin_params['pin']
self._pullup = pin_params['pullup'] self._pullup = pin_params['pullup']
self._invert = pin_params['invert'] self._invert = pin_params['invert']
self._oversample_count = 0
self._oversample_time = 0.
self._cmd_queue = mcu.alloc_command_queue() self._cmd_queue = mcu.alloc_command_queue()
self._oid = self._home_cmd = self._query_cmd = None self._oid = self._home_cmd = self._query_cmd = None
self._homing = False self._homing = False
@ -146,9 +144,6 @@ class MCU_endstop:
self._last_state = {} self._last_state = {}
def get_mcu(self): def get_mcu(self):
return self._mcu return self._mcu
def setup_oversample(self, oversample_count, oversample_time):
self._oversample_count = oversample_count
self._oversample_time = oversample_time
def add_stepper(self, stepper): def add_stepper(self, stepper):
self._steppers.append(stepper) self._steppers.append(stepper)
def build_config(self): def build_config(self):
@ -160,23 +155,21 @@ class MCU_endstop:
self._mcu.add_config_cmd( self._mcu.add_config_cmd(
"end_stop_set_stepper oid=%d pos=%d stepper_oid=%d" % ( "end_stop_set_stepper oid=%d pos=%d stepper_oid=%d" % (
self._oid, i, s.get_oid()), is_init=True) self._oid, i, s.get_oid()), is_init=True)
self._mcu.add_config_cmd(
"end_stop_set_oversample oid=%d sample_ticks=%d sample_count=%d" % (
self._oid, self._mcu.seconds_to_clock(self._oversample_time),
self._oversample_count), is_init=True)
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 sample_ticks=%u sample_count=%c"
" 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 home_start(self, print_time, rest_time): def home_start(self, print_time, sample_time, sample_count, rest_time):
clock = self._mcu.print_time_to_clock(print_time) clock = self._mcu.print_time_to_clock(print_time)
rest_ticks = int(rest_time * self._mcu.get_adjusted_freq()) rest_ticks = int(rest_time * self._mcu.get_adjusted_freq())
self._homing = True self._homing = True
self._min_query_time = self._mcu.monotonic() self._min_query_time = self._mcu.monotonic()
self._next_query_time = print_time + self.RETRY_QUERY self._next_query_time = print_time + self.RETRY_QUERY
msg = self._home_cmd.encode( msg = self._home_cmd.encode(
self._oid, clock, rest_ticks, 1 ^ self._invert) self._oid, clock, self._mcu.seconds_to_clock(sample_time),
sample_count, 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)
for s in self._steppers: for s in self._steppers:
s.note_homing_start(clock) s.note_homing_start(clock)
@ -207,7 +200,7 @@ class MCU_endstop:
return False return False
if print_time > self._home_timeout: if print_time > self._home_timeout:
# Timeout - disable endstop checking # Timeout - disable endstop checking
msg = self._home_cmd.encode(self._oid, 0, 0, 0) msg = self._home_cmd.encode(self._oid, 0, 0, 0, 0, 0)
self._mcu.send(msg, reqclock=0, cq=self._cmd_queue) self._mcu.send(msg, reqclock=0, cq=self._cmd_queue)
raise error("Timeout during endstop homing") raise error("Timeout during endstop homing")
if self._mcu.is_shutdown(): if self._mcu.is_shutdown():

View File

@ -6,9 +6,6 @@
import math, logging import math, logging
import homing, pins import homing, pins
ENDSTOP_OVERSAMPLE_COUNT = 4
ENDSTOP_OVERSAMPLE_TIME = .000015
class PrinterStepper: class PrinterStepper:
def __init__(self, printer, config, name): def __init__(self, printer, config, name):
self.name = name self.name = name
@ -55,8 +52,6 @@ class PrinterHomingStepper(PrinterStepper):
self.mcu_endstop = pins.setup_pin( self.mcu_endstop = pins.setup_pin(
printer, 'endstop', config.get('endstop_pin')) printer, 'endstop', config.get('endstop_pin'))
self.mcu_endstop.setup_oversample(
ENDSTOP_OVERSAMPLE_COUNT, ENDSTOP_OVERSAMPLE_TIME)
self.mcu_endstop.add_stepper(self.mcu_stepper) 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_max = config.getfloat( self.position_max = config.getfloat(

View File

@ -1,6 +1,6 @@
// Handling of end stops. // Handling of end stops.
// //
// Copyright (C) 2016 Kevin O'Connor <kevin@koconnor.net> // Copyright (C) 2016,2017 Kevin O'Connor <kevin@koconnor.net>
// //
// This file may be distributed under the terms of the GNU GPLv3 license. // This file may be distributed under the terms of the GNU GPLv3 license.
@ -13,8 +13,8 @@
struct end_stop { struct end_stop {
struct timer time; struct timer time;
uint32_t rest_time, sample_time;
struct gpio_in pin; struct gpio_in pin;
uint32_t rest_time, sample_time, nextwake;
uint8_t flags, stepper_count, sample_count, trigger_count; uint8_t flags, stepper_count, sample_count, trigger_count;
struct stepper *steppers[0]; struct stepper *steppers[0];
}; };
@ -42,11 +42,13 @@ end_stop_event(struct timer *t)
{ {
struct end_stop *e = container_of(t, struct end_stop, time); struct end_stop *e = container_of(t, struct end_stop, time);
uint8_t val = gpio_in_read(e->pin); uint8_t val = gpio_in_read(e->pin);
uint32_t nextwake = e->time.waketime + e->rest_time;
if ((val ? ~e->flags : e->flags) & ESF_PIN_HIGH) { if ((val ? ~e->flags : e->flags) & ESF_PIN_HIGH) {
// No match - reschedule for the next attempt // No match - reschedule for the next attempt
e->time.waketime += e->rest_time; e->time.waketime = nextwake;
return SF_RESCHEDULE; return SF_RESCHEDULE;
} }
e->nextwake = nextwake;
e->time.func = end_stop_oversample_event; e->time.func = end_stop_oversample_event;
return end_stop_oversample_event(t); return end_stop_oversample_event(t);
} }
@ -60,8 +62,7 @@ end_stop_oversample_event(struct timer *t)
if ((val ? ~e->flags : e->flags) & ESF_PIN_HIGH) { if ((val ? ~e->flags : e->flags) & ESF_PIN_HIGH) {
// No longer matching - reschedule for the next attempt // No longer matching - reschedule for the next attempt
e->time.func = end_stop_event; e->time.func = end_stop_event;
uint8_t past_triggers = e->sample_count - e->trigger_count; e->time.waketime = e->nextwake;
e->time.waketime += e->rest_time - past_triggers * e->sample_time;
e->trigger_count = e->sample_count; e->trigger_count = e->sample_count;
return SF_RESCHEDULE; return SF_RESCHEDULE;
} }
@ -101,18 +102,6 @@ command_end_stop_set_stepper(uint32_t *args)
DECL_COMMAND(command_end_stop_set_stepper, DECL_COMMAND(command_end_stop_set_stepper,
"end_stop_set_stepper oid=%c pos=%c stepper_oid=%c"); "end_stop_set_stepper oid=%c pos=%c stepper_oid=%c");
void
command_end_stop_set_oversample(uint32_t *args)
{
struct end_stop *e = oid_lookup(args[0], command_config_end_stop);
e->sample_time = args[1];
e->sample_count = args[2];
if (!e->sample_count)
e->sample_count = 1;
}
DECL_COMMAND(command_end_stop_set_oversample,
"end_stop_set_oversample oid=%c sample_ticks=%u sample_count=%c");
// Home an axis // Home an axis
void void
command_end_stop_home(uint32_t *args) command_end_stop_home(uint32_t *args)
@ -120,19 +109,22 @@ command_end_stop_home(uint32_t *args)
struct end_stop *e = oid_lookup(args[0], command_config_end_stop); struct end_stop *e = oid_lookup(args[0], command_config_end_stop);
sched_del_timer(&e->time); sched_del_timer(&e->time);
e->time.waketime = args[1]; e->time.waketime = args[1];
e->rest_time = args[2]; e->sample_time = args[2];
if (!e->rest_time) { e->sample_count = args[3];
if (!e->sample_count) {
// Disable end stop checking // Disable end stop checking
e->flags = 0; e->flags = 0;
return; return;
} }
e->rest_time = args[4];
e->time.func = end_stop_event; e->time.func = end_stop_event;
e->trigger_count = e->sample_count; e->trigger_count = e->sample_count;
e->flags = ESF_HOMING | (args[3] ? ESF_PIN_HIGH : 0); e->flags = ESF_HOMING | (args[5] ? ESF_PIN_HIGH : 0);
sched_add_timer(&e->time); sched_add_timer(&e->time);
} }
DECL_COMMAND(command_end_stop_home, DECL_COMMAND(command_end_stop_home,
"end_stop_home oid=%c clock=%u rest_ticks=%u pin_value=%c"); "end_stop_home oid=%c clock=%u sample_ticks=%u sample_count=%c"
" rest_ticks=%u pin_value=%c");
static void static void
end_stop_report(uint8_t oid, struct end_stop *e) end_stop_report(uint8_t oid, struct end_stop *e)