diff --git a/docs/Config_Reference.md b/docs/Config_Reference.md index 8b17d9502..200b9de11 100644 --- a/docs/Config_Reference.md +++ b/docs/Config_Reference.md @@ -4163,6 +4163,7 @@ run_current: #driver_SEDN: 0 #driver_SEIMIN: 0 #driver_SFILT: 0 +#driver_SG4_THRS: 0 #driver_SG4_ANGLE_OFFSET: 1 #driver_SLOPE_CONTROL: 0 # Set the given register during the configuration of the TMC2240 @@ -4176,8 +4177,8 @@ run_current: # is "active low" and is thus normally prefaced with "^!". Setting # this creates a "tmc2240_stepper_x:virtual_endstop" virtual pin # which may be used as the stepper's endstop_pin. Doing this enables -# "sensorless homing". (Be sure to also set driver_SGT to an -# appropriate sensitivity value.) The default is to not enable +# "sensorless homing". (Be sure to also set driver_SGT OR driver_SG4_THRS +# to an appropriate sensitivity value.) The default is to not enable # sensorless homing. ``` diff --git a/klippy/extras/tmc.py b/klippy/extras/tmc.py index 23b05305e..1a2c72251 100644 --- a/klippy/extras/tmc.py +++ b/klippy/extras/tmc.py @@ -575,8 +575,8 @@ class TMCVirtualPinHelper: self.diag_pin = config.get('diag_pin', None) self.diag_pin_field = None self.mcu_endstop = None - self.en_pwm = False - self.pwmthrs = self.coolthrs = self.thigh = 0 + self._dirty_regs = collections.OrderedDict() + self._prev_state = collections.OrderedDict() # Register virtual_endstop pin name_parts = config.get_name().split() ppins = self.printer.lookup_object("pins") @@ -597,56 +597,51 @@ class TMCVirtualPinHelper: self.handle_homing_move_end) self.mcu_endstop = ppins.setup_pin('endstop', self.diag_pin) return self.mcu_endstop + def _set_field(self, field_name, value): + self._prev_state[field_name] = self.fields.get_field(field_name) + reg_name = self.fields.lookup_register(field_name) + self._dirty_regs[reg_name] = self.fields.set_field(field_name, value) + def _send_fields(self): + for reg, val in self._dirty_regs.items(): + self.mcu_tmc.set_register(reg, val) + self._dirty_regs.clear() def handle_homing_move_begin(self, hmove): if self.mcu_endstop not in hmove.get_mcu_endstops(): return + sg4_thrs = 0 + if self.fields.lookup_register("sg4_thrs", None) is not None: + sg4_thrs = self.fields.get_field("sg4_thrs") # Enable/disable stealthchop - self.pwmthrs = self.fields.get_field("tpwmthrs") reg = self.fields.lookup_register("en_pwm_mode", None) if reg is None: # On "stallguard4" drivers, "stealthchop" must be enabled - self.en_pwm = not self.fields.get_field("en_spreadcycle") - tp_val = self.fields.set_field("tpwmthrs", 0) - self.mcu_tmc.set_register("TPWMTHRS", tp_val) - val = self.fields.set_field("en_spreadcycle", 0) + self._set_field("tpwmthrs", 0) + self._set_field("en_spreadcycle", 0) + elif sg4_thrs: + # TMC2240 using SG4, "stealthchop" must be enabled + self._set_field("en_pwm_mode", 1) + self._set_field("tpwmthrs", 0) + self._set_field(self.diag_pin_field, 1) else: # On earlier drivers, "stealthchop" must be disabled - self.en_pwm = self.fields.get_field("en_pwm_mode") - self.fields.set_field("en_pwm_mode", 0) - val = self.fields.set_field(self.diag_pin_field, 1) - self.mcu_tmc.set_register("GCONF", val) + self._set_field("en_pwm_mode", 0) + self._set_field(self.diag_pin_field, 1) # Enable tcoolthrs (if not already) - self.coolthrs = self.fields.get_field("tcoolthrs") - if self.coolthrs == 0: - tc_val = self.fields.set_field("tcoolthrs", 0xfffff) - self.mcu_tmc.set_register("TCOOLTHRS", tc_val) + if self.fields.get_field("tcoolthrs") == 0: + self._set_field("tcoolthrs", 0xfffff) # Disable thigh reg = self.fields.lookup_register("thigh", None) if reg is not None: - self.thigh = self.fields.get_field("thigh") - th_val = self.fields.set_field("thigh", 0) - self.mcu_tmc.set_register(reg, th_val) + self._set_field("thigh", 0) + self._send_fields() def handle_homing_move_end(self, hmove): if self.mcu_endstop not in hmove.get_mcu_endstops(): return - # Restore stealthchop/spreadcycle - reg = self.fields.lookup_register("en_pwm_mode", None) - if reg is None: - tp_val = self.fields.set_field("tpwmthrs", self.pwmthrs) - self.mcu_tmc.set_register("TPWMTHRS", tp_val) - val = self.fields.set_field("en_spreadcycle", not self.en_pwm) - else: - self.fields.set_field("en_pwm_mode", self.en_pwm) - val = self.fields.set_field(self.diag_pin_field, 0) - self.mcu_tmc.set_register("GCONF", val) - # Restore tcoolthrs - tc_val = self.fields.set_field("tcoolthrs", self.coolthrs) - self.mcu_tmc.set_register("TCOOLTHRS", tc_val) - # Restore thigh - reg = self.fields.lookup_register("thigh", None) - if reg is not None: - th_val = self.fields.set_field("thigh", self.thigh) - self.mcu_tmc.set_register(reg, th_val) + # Restore previous state + for field, val in list(self._prev_state.items()): + self._set_field(field, val) + self._send_fields() + self._prev_state.clear() ###################################################################### diff --git a/klippy/extras/tmc2240.py b/klippy/extras/tmc2240.py index d57a93b83..2f114c2aa 100644 --- a/klippy/extras/tmc2240.py +++ b/klippy/extras/tmc2240.py @@ -411,6 +411,7 @@ class TMC2240: # TPOWERDOWN set_config_field(config, "tpowerdown", 10) # SG4_THRS + set_config_field(config, "sg4_thrs", 0) set_config_field(config, "sg4_angle_offset", 1) # DRV_CONF set_config_field(config, "slope_control", 0)