From a0829c63ded2b039e4aa0cc2ba5b5ca343a8ff82 Mon Sep 17 00:00:00 2001 From: Kevin O'Connor Date: Mon, 28 Nov 2016 14:52:22 -0500 Subject: [PATCH] serialhdl: Make SerialReader.send_with_response() blocking Use the greenlet mechanism to wait for the response directly in the send_with_response() method. This simplifies the calling code. Signed-off-by: Kevin O'Connor --- klippy/mcu.py | 53 +++++++++++++++------------------------------ klippy/serialhdl.py | 27 ++++++++++++++--------- 2 files changed, 35 insertions(+), 45 deletions(-) diff --git a/klippy/mcu.py b/klippy/mcu.py index 11581f55..a665ad32 100644 --- a/klippy/mcu.py +++ b/klippy/mcu.py @@ -337,10 +337,6 @@ class MCU: self.serial.dump_debug() self._printer.shutdown() # Connection phase - def _init_steppersync(self, count): - stepqueues = tuple(s._stepqueue for s in self._steppers) - self._steppersync = self.ffi_lib.steppersync_alloc( - self.serial.serialqueue, stepqueues, len(stepqueues), count) def connect(self): if not self._is_fileoutput: self.serial.connect() @@ -351,13 +347,6 @@ class MCU: def connect_file(self, debugoutput, dictionary, pace=False): self._is_fileoutput = True self.serial.connect_file(debugoutput, dictionary) - def dummy_send_config(): - for c in self._config_cmds: - self.send(self.create_command(c)) - self._init_steppersync(500) - for cb in self._init_callbacks: - cb() - self._send_config = dummy_send_config if not pace: def dummy_set_print_start_time(eventtime): pass @@ -416,31 +405,25 @@ class MCU: self._send_config() def _send_config(self): msg = self.create_command("get_config") - config_params = {} - sent_config = False - def handle_get_config(params): - config_params.update(params) - return True - while 1: - self.serial.send_with_response(msg, handle_get_config, 'config') - while 1: - is_config = config_params.get('is_config') - if is_config is not None and (not sent_config or is_config): - break - self._printer.reactor.pause(time.time() + 0.05) - if not is_config: - # Send config commands - for c in self._config_cmds: - self.send(self.create_command(c)) - config_params.clear() - sent_config = True - continue - if self._config_crc != config_params['crc']: - logging.error("Printer CRC does not match config") - sys.exit(1) - break + if self._is_fileoutput: + config_params = { + 'is_config': 0, 'move_count': 500, 'crc': self._config_crc} + else: + config_params = self.serial.send_with_response(msg, 'config') + if not config_params['is_config']: + # Send config commands + for c in self._config_cmds: + self.send(self.create_command(c)) + if not self._is_fileoutput: + config_params = self.serial.send_with_response(msg, 'config') + if self._config_crc != config_params['crc']: + logging.error("Printer CRC does not match config") + sys.exit(1) logging.info("Configured") - self._init_steppersync(config_params['move_count']) + stepqueues = tuple(s._stepqueue for s in self._steppers) + self._steppersync = self.ffi_lib.steppersync_alloc( + self.serial.serialqueue, stepqueues, len(stepqueues), + config_params['move_count']) for cb in self._init_callbacks: cb() # Config creation helpers diff --git a/klippy/serialhdl.py b/klippy/serialhdl.py index 09b775cc..a0b3a4ed 100644 --- a/klippy/serialhdl.py +++ b/klippy/serialhdl.py @@ -146,8 +146,9 @@ class SerialReader: def encode_and_send(self, data, minclock, reqclock, cq): self.ffi_lib.serialqueue_encode_and_send( self.serialqueue, cq, data, len(data), minclock, reqclock) - def send_with_response(self, cmd, callback, name): - SerialRetryCommand(self, cmd, callback, name) + def send_with_response(self, cmd, name): + src = SerialRetryCommand(self, cmd, name) + return src.get_response() def send_flush(self): self.ffi_lib.serialqueue_flush_ready(self.serialqueue) def alloc_command_queue(self): @@ -207,25 +208,31 @@ class SerialReader: # Class to retry sending of a query command until a given response is received class SerialRetryCommand: RETRY_TIME = 0.500 - def __init__(self, serial, cmd, callback, name): + def __init__(self, serial, cmd, name): self.serial = serial self.cmd = cmd - self.callback = callback self.name = name + self.response = None + self.min_query_time = time.time() self.serial.register_callback(self.handle_callback, self.name) self.send_timer = self.serial.reactor.register_timer( self.send_event, self.serial.reactor.NOW) def send_event(self, eventtime): - if self.callback is None: - self.serial.reactor.unregister_timer(self.send_timer) + if self.response is not None: return self.serial.reactor.NEVER self.serial.send(self.cmd) return eventtime + self.RETRY_TIME def handle_callback(self, params): - done = self.callback(params) - if done: - self.serial.unregister_callback(self.name) - self.callback = None + last_sent_time = params['#sent_time'] + if last_sent_time >= self.min_query_time: + self.response = params + def get_response(self): + eventtime = time.time() + while self.response is None: + eventtime = self.serial.reactor.pause(eventtime + 0.05) + self.serial.unregister_callback(self.name) + self.serial.reactor.unregister_timer(self.send_timer) + return self.response # Code to start communication and download message type dictionary class SerialBootStrap: