From 69dcda1696a04e303f70632a09869f3cc57bb94f Mon Sep 17 00:00:00 2001 From: Kevin O'Connor Date: Fri, 13 Jan 2023 12:08:47 -0500 Subject: [PATCH] mcu: Code movement in mcu.py This is code movement and comment updates only - no code changes. Signed-off-by: Kevin O'Connor --- klippy/mcu.py | 161 +++++++++++++++++++++++++++----------------------- 1 file changed, 88 insertions(+), 73 deletions(-) diff --git a/klippy/mcu.py b/klippy/mcu.py index ce1fee4c..fbd0b5a4 100644 --- a/klippy/mcu.py +++ b/klippy/mcu.py @@ -1,6 +1,6 @@ # Interface to Klipper micro-controller code # -# Copyright (C) 2016-2021 Kevin O'Connor +# Copyright (C) 2016-2023 Kevin O'Connor # # This file may be distributed under the terms of the GNU GPLv3 license. import sys, os, zlib, logging, math @@ -9,6 +9,90 @@ import serialhdl, msgproto, pins, chelper, clocksync class error(Exception): pass + +###################################################################### +# Command transmit helper classes +###################################################################### + +# 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, serial, name, oid=None): + self.serial = serial + self.name = name + self.oid = oid + self.reactor = serial.get_reactor() + 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, cmds, cmd_queue, minclock=0, reqclock=0): + cmd, = cmds + self.serial.raw_send_wait_ack(cmd, minclock, reqclock, cmd_queue) + first_query_time = query_time = self.reactor.monotonic() + while 1: + 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 serialhdl.error("Timeout on wait for '%s' response" + % (self.name,)) + self.serial.raw_send(cmd, minclock, minclock, cmd_queue) + +# Wrapper around query commands +class CommandQueryWrapper: + def __init__(self, serial, msgformat, respformat, oid=None, + cmd_queue=None, is_async=False, error=serialhdl.error): + self._serial = serial + self._cmd = serial.get_msgparser().lookup_command(msgformat) + serial.get_msgparser().lookup_command(respformat) + self._response = respformat.split()[0] + self._oid = oid + self._error = error + self._xmit_helper = serialhdl.SerialRetryCommand + if is_async: + self._xmit_helper = RetryAsyncCommand + if cmd_queue is None: + cmd_queue = serial.get_default_command_queue() + self._cmd_queue = cmd_queue + def _do_send(self, cmds, minclock, reqclock): + xh = self._xmit_helper(self._serial, self._response, self._oid) + reqclock = max(minclock, reqclock) + try: + return xh.get_response(cmds, self._cmd_queue, minclock, reqclock) + except serialhdl.error as e: + raise self._error(str(e)) + def send(self, data=(), minclock=0, reqclock=0): + return self._do_send([self._cmd.encode(data)], minclock, reqclock) + def send_with_preface(self, preface_cmd, preface_data=(), data=(), + minclock=0, reqclock=0): + cmds = [preface_cmd._cmd.encode(preface_data), self._cmd.encode(data)] + return self._do_send(cmds, minclock, reqclock) + +# Wrapper around command sending +class CommandWrapper: + def __init__(self, serial, msgformat, cmd_queue=None): + self._serial = serial + self._cmd = serial.get_msgparser().lookup_command(msgformat) + if cmd_queue is None: + cmd_queue = serial.get_default_command_queue() + self._cmd_queue = cmd_queue + def send(self, data=(), minclock=0, reqclock=0): + cmd = self._cmd.encode(data) + self._serial.raw_send(cmd, minclock, reqclock, self._cmd_queue) + + +###################################################################### +# Wrapper classes for MCU pins +###################################################################### + class MCU_trsync: REASON_ENDSTOP_HIT = 1 REASON_COMMS_TIMEOUT = 2 @@ -456,79 +540,10 @@ 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, serial, name, oid=None): - self.serial = serial - self.name = name - self.oid = oid - self.reactor = serial.get_reactor() - 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, cmds, cmd_queue, minclock=0, reqclock=0): - cmd, = cmds - self.serial.raw_send_wait_ack(cmd, minclock, reqclock, cmd_queue) - first_query_time = query_time = self.reactor.monotonic() - while 1: - 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 serialhdl.error("Timeout on wait for '%s' response" - % (self.name,)) - self.serial.raw_send(cmd, minclock, minclock, cmd_queue) -# Wrapper around query commands -class CommandQueryWrapper: - def __init__(self, serial, msgformat, respformat, oid=None, - cmd_queue=None, is_async=False, error=serialhdl.error): - self._serial = serial - self._cmd = serial.get_msgparser().lookup_command(msgformat) - serial.get_msgparser().lookup_command(respformat) - self._response = respformat.split()[0] - self._oid = oid - self._error = error - self._xmit_helper = serialhdl.SerialRetryCommand - if is_async: - self._xmit_helper = RetryAsyncCommand - if cmd_queue is None: - cmd_queue = serial.get_default_command_queue() - self._cmd_queue = cmd_queue - def _do_send(self, cmds, minclock, reqclock): - xh = self._xmit_helper(self._serial, self._response, self._oid) - reqclock = max(minclock, reqclock) - try: - return xh.get_response(cmds, self._cmd_queue, minclock, reqclock) - except serialhdl.error as e: - raise self._error(str(e)) - def send(self, data=(), minclock=0, reqclock=0): - return self._do_send([self._cmd.encode(data)], minclock, reqclock) - def send_with_preface(self, preface_cmd, preface_data=(), data=(), - minclock=0, reqclock=0): - cmds = [preface_cmd._cmd.encode(preface_data), self._cmd.encode(data)] - return self._do_send(cmds, minclock, reqclock) - -# Wrapper around command sending -class CommandWrapper: - def __init__(self, serial, msgformat, cmd_queue=None): - self._serial = serial - self._cmd = serial.get_msgparser().lookup_command(msgformat) - if cmd_queue is None: - cmd_queue = serial.get_default_command_queue() - self._cmd_queue = cmd_queue - def send(self, data=(), minclock=0, reqclock=0): - cmd = self._cmd.encode(data) - self._serial.raw_send(cmd, minclock, reqclock, self._cmd_queue) +###################################################################### +# Main MCU class +###################################################################### class MCU: error = error