aboutsummaryrefslogtreecommitdiffstats
path: root/klippy/mcu.py
diff options
context:
space:
mode:
authorKevin O'Connor <kevin@koconnor.net>2020-02-16 15:46:04 -0500
committerKevin O'Connor <kevin@koconnor.net>2020-02-20 12:01:21 -0500
commit332038ea017d458c27f1bb69fa7c17bfe36fcbd8 (patch)
tree9a9e8c04efffcc425219f063c0acb04e00c6e077 /klippy/mcu.py
parentc6c360c4e14374a56dcb0477e1e7759683841093 (diff)
downloadkutter-332038ea017d458c27f1bb69fa7c17bfe36fcbd8.tar.gz
kutter-332038ea017d458c27f1bb69fa7c17bfe36fcbd8.tar.xz
kutter-332038ea017d458c27f1bb69fa7c17bfe36fcbd8.zip
serialhdl: Convert queries to use new notify message ack system
Convert standard queries to use the acknowledgments of the sent command to determine if the response was received or not. This also controls command retransmissions (should the response have been lost). The tmc_uart.py will continue to use the old mechanism as the tmcuart responses are not sent synchronously with the query command. Signed-off-by: Kevin O'Connor <kevin@koconnor.net>
Diffstat (limited to 'klippy/mcu.py')
-rw-r--r--klippy/mcu.py43
1 files changed, 38 insertions, 5 deletions
diff --git a/klippy/mcu.py b/klippy/mcu.py
index 09f5d232..4be952f2 100644
--- a/klippy/mcu.py
+++ b/klippy/mcu.py
@@ -301,6 +301,35 @@ class MCU_adc:
if self._callback is not None:
self._callback(last_read_time, last_value)
+# Class to retry sending of a query command until a given response is received
+class RetryAsyncCommand:
+ TIMEOUT_TIME = 5.0
+ RETRY_TIME = 0.500
+ def __init__(self, mcu, serial, name, oid=None):
+ self.reactor = mcu.get_printer().get_reactor()
+ self.serial = serial
+ self.name = name
+ self.oid = oid
+ self.completion = self.reactor.completion()
+ self.min_query_time = self.reactor.monotonic()
+ self.serial.register_response(self.handle_callback, name, oid)
+ def handle_callback(self, params):
+ if params['#sent_time'] >= self.min_query_time:
+ self.min_query_time = self.reactor.NEVER
+ self.reactor.async_complete(self.completion, params)
+ def get_response(self, cmd, cmd_queue, minclock=0, minsystime=0.):
+ first_query_time = query_time = max(self.min_query_time, minsystime)
+ while 1:
+ self.serial.raw_send(cmd, minclock, minclock, cmd_queue)
+ params = self.completion.wait(query_time + self.RETRY_TIME)
+ if params is not None:
+ self.serial.register_response(None, self.name, self.oid)
+ return params
+ query_time = self.reactor.monotonic()
+ if query_time > first_query_time + self.TIMEOUT_TIME:
+ self.serial.register_response(None, self.name, self.oid)
+ raise error("Timeout on wait for '%s' response" % (self.name,))
+
# Wrapper around command sending
class CommandWrapper:
def __init__(self, mcu, serial, clocksync, cmd, cmd_queue):
@@ -314,16 +343,20 @@ class CommandWrapper:
self._serial.raw_send(cmd, minclock, reqclock, self._cmd_queue)
def send_with_response(self, data=(), response=None, response_oid=None,
minclock=0):
- minsystime = 0.
- if minclock:
- minsystime = self._clocksync.estimate_clock_systime(minclock)
cmd = self._cmd.encode(data)
src = serialhdl.SerialRetryCommand(self._serial, response, response_oid)
try:
- return src.get_response([cmd], self._cmd_queue,
- minclock=minclock, minsystime=minsystime)
+ return src.get_response(cmd, self._cmd_queue, minclock=minclock)
except serialhdl.error as e:
raise error(str(e))
+ def send_with_async_response(self, data=(),
+ response=None, response_oid=None, minclock=0):
+ minsystime = 0.
+ if minclock:
+ minsystime = self._clocksync.estimate_clock_systime(minclock)
+ cmd = self._cmd.encode(data)
+ src = RetryAsyncCommand(self._mcu, self._serial, response, response_oid)
+ return src.get_response(cmd, self._cmd_queue, minclock, minsystime)
class MCU:
error = error