Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
16 changes: 13 additions & 3 deletions klippy/clocksync.py
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,11 @@

RTT_AGE = 0.000010 / (60.0 * 60.0)
DECAY = 1.0 / 30.0
TRANSMIT_EXTRA = 0.001
# Default forward-scheduling headroom added to the clock estimate sent
# to the serialqueue. Can be overridden via [danger_options]
# transmit_extra. Increase this (e.g. to 0.003-0.005) if you
# experience 'Timer too close' shutdowns on a heavily loaded host.
TRANSMIT_EXTRA = 0.002


class ClockSync:
Expand All @@ -30,6 +34,11 @@ def __init__(self, reactor):
self.clock_avg = self.clock_covariance = 0.0
self.prediction_variance = 0.0
self.last_prediction_time = 0.0
self.transmit_extra = TRANSMIT_EXTRA

def set_transmit_extra(self, value):
"""Override the transmit_extra headroom (called from danger_options)."""
self.transmit_extra = value

def disconnect(self):
self.reactor.update_timer(self.get_clock_timer, self.reactor.NEVER)
Expand Down Expand Up @@ -145,7 +154,7 @@ def _handle_clock(self, params):
pred_stddev = math.sqrt(self.prediction_variance)
self.serial.set_clock_est(
new_freq,
self.time_avg + TRANSMIT_EXTRA,
self.time_avg + self.transmit_extra,
int(self.clock_avg - 3.0 * pred_stddev),
clock,
)
Expand Down Expand Up @@ -192,7 +201,7 @@ def dump_debug(self):
"clocksync state: mcu_freq=%d last_clock=%d"
" clock_est=(%.3f %d %.3f) min_half_rtt=%.6f min_rtt_time=%.3f"
" time_avg=%.3f(%.3f) clock_avg=%.3f(%.3f)"
" pred_variance=%.3f"
" pred_variance=%.3f transmit_extra=%.6f"
% (
self.mcu_freq,
self.last_clock,
Expand All @@ -206,6 +215,7 @@ def dump_debug(self):
self.clock_avg,
self.clock_covariance,
self.prediction_variance,
self.transmit_extra,
)
)

Expand Down
27 changes: 27 additions & 0 deletions klippy/extras/danger_options.py
Original file line number Diff line number Diff line change
@@ -1,3 +1,6 @@
from ..clocksync import TRANSMIT_EXTRA


class DangerOptions:
def __init__(self, config):
self.minimal_logging = config.getboolean("minimal_logging", False)
Expand Down Expand Up @@ -38,6 +41,14 @@ def __init__(self, config):
self.homing_elapsed_distance_tolerance = config.getfloat(
"homing_elapsed_distance_tolerance", 0.5, minval=0.0
)
# transmit_extra: forward-scheduling headroom (seconds) added to the
# MCU clock estimate passed to the serialqueue. Increasing this helps
# prevent 'Timer too close' MCU shutdowns on hosts that experience CPU
# or scheduling jitter. See docs/Config_Reference.md ([danger_options])
# for guidance.
self.transmit_extra = config.getfloat(
"transmit_extra", TRANSMIT_EXTRA, minval=0.0, maxval=0.010
)

temp_ignore_limits = False
if config.getboolean("temp_ignore_limits", None) is None:
Expand Down Expand Up @@ -78,4 +89,20 @@ def get_danger_options():
def load_config(config):
global DANGER_OPTIONS
DANGER_OPTIONS = DangerOptions(config)
# Apply transmit_extra to all ClockSync instances already registered
printer = config.get_printer()
# Wire transmit_extra into MCU clocksync objects at connect time
printer.register_event_handler(
"klippy:mcu_identify",
lambda: _apply_transmit_extra(printer, DANGER_OPTIONS.transmit_extra),
)
return DANGER_OPTIONS


def _apply_transmit_extra(printer, value):
"""Push transmit_extra into all MCU clocksync objects."""
for name, obj in printer.objects.items():
if name == "mcu" or name.startswith("mcu "):
clocksync = getattr(obj, "_clocksync", None)
if clocksync is not None and hasattr(clocksync, "set_transmit_extra"):
clocksync.set_transmit_extra(value)
Loading