From e9bf2d4c5c02e8fbf1130928bf08f8de37e6ee79 Mon Sep 17 00:00:00 2001 From: Kevin O'Connor Date: Thu, 21 Sep 2023 14:42:44 -0400 Subject: [PATCH] mcu: Enhance RetryAsyncCommand to handle low-level retransmits The RetryAsyncCommand code needs to ensure that any response messages are not from a previous (unrelated) query. To do that it compares the '#sent_time' from potential responses to ensure they are not from a previous session. However, if there are any low-level serial retransmits then the low-level code sets the '#sent_time' to zero (to indicate that the query send time is not strictly known). That could result in a valid response not being accepted by RetryAsyncCommand. If a low-level connection is experiencing a small amount of periodic retransmits it could result in multiple high-level retry attempts failing to the point that there is a user-facing error. This could result in "Timeout on wait for 'tmcuart_response' response" errors. Fix by accepting responses even if there is a low-level retransmit once the code can confirm that there can be no previous query still in progress. Signed-off-by: Kevin O'Connor --- klippy/mcu.py | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/klippy/mcu.py b/klippy/mcu.py index 76c70506ba4a..68179bdd4ffd 100644 --- a/klippy/mcu.py +++ b/klippy/mcu.py @@ -25,14 +25,16 @@ def __init__(self, serial, name, oid=None): self.reactor = serial.get_reactor() self.completion = self.reactor.completion() self.min_query_time = self.reactor.monotonic() + self.need_response = True 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 + if self.need_response and params['#sent_time'] >= self.min_query_time: + self.need_response = False self.reactor.async_complete(self.completion, params) def get_response(self, cmds, cmd_queue, minclock=0, reqclock=0): cmd, = cmds self.serial.raw_send_wait_ack(cmd, minclock, reqclock, cmd_queue) + self.min_query_time = 0. first_query_time = query_time = self.reactor.monotonic() while 1: params = self.completion.wait(query_time + self.RETRY_TIME)