From ff9543eee2c41befe5945ec7a60d102d03026472 Mon Sep 17 00:00:00 2001 From: Kevin O'Connor Date: Thu, 31 May 2018 18:18:23 -0400 Subject: [PATCH] clocksync: Simplify is_active() check In some rare circumstances it was possible for the host software to become so busy that it does not transmit a get_clock request for several seconds. (In particular, this could occur with some complex calls to coordinate_descent.) If that happened, it was possible for the code to incorrectly report a "Timeout with MCU" error. Rework the is_active() check to prevent that. Signed-off-by: Kevin O'Connor --- klippy/clocksync.py | 14 +++++++------- klippy/mcu.py | 4 ++-- 2 files changed, 9 insertions(+), 9 deletions(-) diff --git a/klippy/clocksync.py b/klippy/clocksync.py index 9c58e6fa..07e78513 100644 --- a/klippy/clocksync.py +++ b/klippy/clocksync.py @@ -1,11 +1,10 @@ # Micro-controller clock synchronization # -# Copyright (C) 2016,2017 Kevin O'Connor +# Copyright (C) 2016-2018 Kevin O'Connor # # This file may be distributed under the terms of the GNU GPLv3 license. -import logging, threading, math +import logging, math -COMM_TIMEOUT = 3.5 RTT_AGE = .000010 / (60. * 60.) DECAY = 1. / 30. TRANSMIT_EXTRA = .001 @@ -16,6 +15,7 @@ class ClockSync: self.serial = None self.get_clock_timer = self.reactor.register_timer(self._get_clock_event) self.get_clock_cmd = None + self.queries_pending = 0 self.mcu_freq = 1. self.last_clock = 0 self.clock_est = (0., 0., 0.) @@ -57,10 +57,12 @@ class ClockSync: # MCU clock querying (_handle_clock is invoked from background thread) def _get_clock_event(self, eventtime): self.get_clock_cmd.send() + self.queries_pending += 1 # Use an unusual time for the next event so clock messages # don't resonate with other periodic events. return eventtime + .9839 def _handle_clock(self, params): + self.queries_pending = 0 # Extend clock to 64bit last_clock = self.last_clock clock = (last_clock & ~0xffffffff) | params['clock'] @@ -138,10 +140,8 @@ class ClockSync: if clock_diff & 0x80000000: return last_clock + 0x100000000 - clock_diff return last_clock - clock_diff - def is_active(self, eventtime): - print_time = self.estimated_print_time(eventtime) - last_clock_print_time = self.clock_to_print_time(self.last_clock) - return print_time < last_clock_print_time + COMM_TIMEOUT + def is_active(self): + return self.queries_pending <= 4 def dump_debug(self): sample_time, clock, freq = self.clock_est return ("clocksync state: mcu_freq=%d last_clock=%d" diff --git a/klippy/mcu.py b/klippy/mcu.py index 2209ce4e..dd9df40d 100644 --- a/klippy/mcu.py +++ b/klippy/mcu.py @@ -690,7 +690,7 @@ class MCU: serialhdl.arduino_reset(self._serialport, self._reactor) def _restart_via_command(self): if ((self._reset_cmd is None and self._config_reset_cmd is None) - or not self._clocksync.is_active(self._reactor.monotonic())): + or not self._clocksync.is_active()): logging.info("Unable to issue reset command on MCU '%s'", self._name) return if self._reset_cmd is None: @@ -739,7 +739,7 @@ class MCU: return offset, freq = self._clocksync.calibrate_clock(print_time, eventtime) self._ffi_lib.steppersync_set_time(self._steppersync, offset, freq) - if (self._clocksync.is_active(eventtime) or self.is_fileoutput() + if (self._clocksync.is_active() or self.is_fileoutput() or self._is_timeout): return self._is_timeout = True