extruder: Add support for reversing the direction of extruder stepper movement

Extend SET_EXTRUDER_ROTATION_DISTANCE to support reversing the
direction of extruder movement.

Signed-off-by: Kevin O'Connor <kevin@koconnor.net>
This commit is contained in:
Kevin O'Connor 2022-01-29 19:13:31 -05:00
parent 189188e3ca
commit 9ec9742484
9 changed files with 60 additions and 19 deletions

View file

@ -38,8 +38,9 @@ defs_stepcompress = """
struct stepcompress *stepcompress_alloc(uint32_t oid);
void stepcompress_fill(struct stepcompress *sc, uint32_t max_error
, uint32_t invert_sdir, int32_t queue_step_msgtag
, int32_t set_next_step_dir_msgtag);
, int32_t queue_step_msgtag, int32_t set_next_step_dir_msgtag);
void stepcompress_set_invert_sdir(struct stepcompress *sc
, uint32_t invert_sdir);
void stepcompress_free(struct stepcompress *sc);
int stepcompress_reset(struct stepcompress *sc, uint64_t last_step_clock);
int stepcompress_set_last_position(struct stepcompress *sc

View file

@ -259,15 +259,25 @@ stepcompress_alloc(uint32_t oid)
// Fill message id information
void __visible
stepcompress_fill(struct stepcompress *sc, uint32_t max_error
, uint32_t invert_sdir, int32_t queue_step_msgtag
, int32_t set_next_step_dir_msgtag)
, int32_t queue_step_msgtag, int32_t set_next_step_dir_msgtag)
{
sc->max_error = max_error;
sc->invert_sdir = !!invert_sdir;
sc->queue_step_msgtag = queue_step_msgtag;
sc->set_next_step_dir_msgtag = set_next_step_dir_msgtag;
}
// Set the inverted stepper direction flag
void __visible
stepcompress_set_invert_sdir(struct stepcompress *sc, uint32_t invert_sdir)
{
invert_sdir = !!invert_sdir;
if (invert_sdir != sc->invert_sdir) {
sc->invert_sdir = invert_sdir;
if (sc->sdir >= 0)
sc->sdir ^= 1;
}
}
// Helper to free items from the history_list
static void
free_history(struct stepcompress *sc, uint64_t end_clock)

View file

@ -13,8 +13,10 @@ struct pull_history_steps {
struct stepcompress *stepcompress_alloc(uint32_t oid);
void stepcompress_fill(struct stepcompress *sc, uint32_t max_error
, uint32_t invert_sdir, int32_t queue_step_msgtag
, int32_t queue_step_msgtag
, int32_t set_next_step_dir_msgtag);
void stepcompress_set_invert_sdir(struct stepcompress *sc
, uint32_t invert_sdir);
void stepcompress_free(struct stepcompress *sc);
uint32_t stepcompress_get_oid(struct stepcompress *sc);
int stepcompress_get_step_dir(struct stepcompress *sc);

View file

@ -139,7 +139,7 @@ class DumpStepper:
mcu_pos = first.start_position
start_position = self.mcu_stepper.mcu_to_commanded_position(mcu_pos)
step_dist = self.mcu_stepper.get_step_dist()
if self.mcu_stepper.is_dir_inverted():
if self.mcu_stepper.get_dir_inverted()[0]:
step_dist = -step_dist
d = [(s.interval, s.step_count, s.add) for s in data]
return {"data": d, "start_position": start_position,

View file

@ -224,6 +224,8 @@ class TMCCommandHelper:
self.stepper_enable = self.printer.load_object(config, "stepper_enable")
self.printer.register_event_handler("stepper:sync_mcu_position",
self._handle_sync_mcu_pos)
self.printer.register_event_handler("stepper:set_sdir_inverted",
self._handle_sync_mcu_pos)
self.printer.register_event_handler("klippy:mcu_identify",
self._handle_mcu_identify)
self.printer.register_event_handler("klippy:connect",
@ -306,7 +308,7 @@ class TMCCommandHelper:
if enable_line.is_motor_enabled():
raise
return
if not stepper.is_dir_inverted():
if not stepper.get_dir_inverted()[0]:
driver_phase = 1023 - driver_phase
phases = self._get_phases()
phase = int(float(driver_phase) / 1024 * phases + .5) % phases

View file

@ -91,13 +91,24 @@ class ExtruderStepper:
gcmd.respond_info(msg, log=False)
cmd_SET_E_ROTATION_DISTANCE_help = "Set extruder rotation distance"
def cmd_SET_E_ROTATION_DISTANCE(self, gcmd):
rotation_dist = gcmd.get_float('DISTANCE', None, above=0.)
rotation_dist = gcmd.get_float('DISTANCE', None)
if rotation_dist is not None:
if not rotation_dist:
raise gcmd.error("Rotation distance can not be zero")
invert_dir, orig_invert_dir = self.stepper.get_dir_inverted()
next_invert_dir = orig_invert_dir
if rotation_dist < 0.:
next_invert_dir = not orig_invert_dir
rotation_dist = -rotation_dist
toolhead = self.printer.lookup_object('toolhead')
toolhead.flush_step_generation()
self.stepper.set_rotation_distance(rotation_dist)
self.stepper.set_dir_inverted(next_invert_dir)
else:
rotation_dist, spr = self.stepper.get_rotation_distance()
invert_dir, orig_invert_dir = self.stepper.get_dir_inverted()
if invert_dir != orig_invert_dir:
rotation_dist = -rotation_dist
gcmd.respond_info("Extruder '%s' rotation distance set to %0.6f"
% (self.name, rotation_dist))
cmd_SET_E_STEP_DISTANCE_help = "Set extruder step distance"

View file

@ -36,7 +36,7 @@ class MCU_stepper:
raise self._mcu.get_printer().config_error(
"Stepper dir pin must be on same mcu as step pin")
self._dir_pin = dir_pin_params['pin']
self._invert_dir = dir_pin_params['invert']
self._invert_dir = self._orig_invert_dir = dir_pin_params['invert']
self._step_both_edge = self._req_step_both_edge = False
self._mcu_position_offset = 0.
self._reset_cmd_tag = self._get_position_cmd = None
@ -44,6 +44,7 @@ class MCU_stepper:
ffi_main, ffi_lib = chelper.get_ffi()
self._stepqueue = ffi_main.gc(ffi_lib.stepcompress_alloc(oid),
ffi_lib.stepcompress_free)
ffi_lib.stepcompress_set_invert_sdir(self._stepqueue, self._invert_dir)
self._mcu.register_stepqueue(self._stepqueue)
self._stepper_kinematics = None
self._itersolve_generate_steps = ffi_lib.itersolve_generate_steps
@ -101,7 +102,7 @@ class MCU_stepper:
max_error_ticks = self._mcu.seconds_to_clock(max_error)
ffi_main, ffi_lib = chelper.get_ffi()
ffi_lib.stepcompress_fill(self._stepqueue, max_error_ticks,
self._invert_dir, step_cmd_tag, dir_cmd_tag)
step_cmd_tag, dir_cmd_tag)
def get_oid(self):
return self._oid
def get_step_dist(self):
@ -114,8 +115,16 @@ class MCU_stepper:
self._step_dist = rotation_dist / self._steps_per_rotation
self.set_stepper_kinematics(self._stepper_kinematics)
self._set_mcu_position(mcu_pos)
def is_dir_inverted(self):
return self._invert_dir
def get_dir_inverted(self):
return self._invert_dir, self._orig_invert_dir
def set_dir_inverted(self, invert_dir):
invert_dir = not not invert_dir
if invert_dir == self._invert_dir:
return
self._invert_dir = invert_dir
ffi_main, ffi_lib = chelper.get_ffi()
ffi_lib.stepcompress_set_invert_sdir(self._stepqueue, invert_dir)
self._mcu.get_printer().send_event("stepper:set_dir_inverted", self)
def calc_position_from_coord(self, coord):
ffi_main, ffi_lib = chelper.get_ffi()
return ffi_lib.itersolve_calc_position_from_coord(