From 535c7b99b43baf50272c71fcaf52b10f1a707175 Mon Sep 17 00:00:00 2001 From: Kevin O'Connor Date: Sun, 27 Nov 2016 17:45:58 -0500 Subject: [PATCH] serialhdl: Make SerialReader.connect() blocking Use the greenlet mechanism to wait for the connection to come up in the serial connect() method. This simplifies the calling code. Signed-off-by: Kevin O'Connor --- klippy/console.py | 8 +++++-- klippy/klippy.py | 3 --- klippy/mcu.py | 12 ++-------- klippy/serialhdl.py | 53 ++++++++++++++++++++++----------------------- 4 files changed, 34 insertions(+), 42 deletions(-) diff --git a/klippy/console.py b/klippy/console.py index 21cd5f4d..94476007 100755 --- a/klippy/console.py +++ b/klippy/console.py @@ -18,9 +18,14 @@ class KeyboardReader: util.set_nonblock(self.fd) self.pins = None self.data = "" - self.reactor.register_fd(self.fd, self.process_kbd) + reactor.register_fd(self.fd, self.process_kbd) + self.connect_timer = reactor.register_timer(self.connect, reactor.NOW) self.local_commands = { "PINS": self.set_pin_map, "SET": self.set_var } self.eval_globals = {} + def connect(self, eventtime): + self.ser.connect() + self.reactor.unregister_timer(self.connect_timer) + return self.reactor.NEVER def update_evals(self, eventtime): f = self.ser.msgparser.config.get('CLOCK_FREQ', 1) c = self.ser.get_clock(eventtime) @@ -101,7 +106,6 @@ def main(): logging.basicConfig(level=logging.DEBUG) r = reactor.Reactor() ser = serialhdl.SerialReader(r, serialport, baud) - ser.connect() kbd = KeyboardReader(ser, r) try: r.run() diff --git a/klippy/klippy.py b/klippy/klippy.py index ed71d699..2f82cfe5 100644 --- a/klippy/klippy.py +++ b/klippy/klippy.py @@ -85,9 +85,6 @@ class Printer: def connect_file(self, output, dictionary): self.reactor.update_timer(self.stats_timer, self.reactor.NEVER) self.mcu.connect_file(output, dictionary) - self.build_config() - self.gcode.run() - self.reactor.unregister_timer(self.connect_timer) def run(self): self.reactor.run() # If gcode exits, then exit the MCU diff --git a/klippy/mcu.py b/klippy/mcu.py index d279a847..11581f55 100644 --- a/klippy/mcu.py +++ b/klippy/mcu.py @@ -342,15 +342,8 @@ class MCU: self._steppersync = self.ffi_lib.steppersync_alloc( self.serial.serialqueue, stepqueues, len(stepqueues), count) def connect(self): - state_params = {} - def handle_serial_state(params): - state_params.update(params) - self.serial.register_callback(handle_serial_state, '#state') - self.serial.connect() - while state_params.get('#state') != 'connected': - self._printer.reactor.pause(time.time() + 0.05) - self.serial.unregister_callback('#state') - logging.info("serial connected") + if not self._is_fileoutput: + self.serial.connect() self._mcu_freq = float(self.serial.msgparser.config['CLOCK_FREQ']) self.register_msg(self.handle_shutdown, 'shutdown') self.register_msg(self.handle_shutdown, 'is_shutdown') @@ -358,7 +351,6 @@ class MCU: def connect_file(self, debugoutput, dictionary, pace=False): self._is_fileoutput = True self.serial.connect_file(debugoutput, dictionary) - self._mcu_freq = float(self.serial.msgparser.config['CLOCK_FREQ']) def dummy_send_config(): for c in self._config_cmds: self.send(self.create_command(c)) diff --git a/klippy/serialhdl.py b/klippy/serialhdl.py index a52a8130..09b775cc 100644 --- a/klippy/serialhdl.py +++ b/klippy/serialhdl.py @@ -34,7 +34,7 @@ class SerialReader: self._status_event, self.reactor.NOW) self.status_cmd = None handlers = { - '#unknown': self.handle_unknown, '#state': self.handle_state, + '#unknown': self.handle_unknown, '#output': self.handle_output, 'status': self.handle_status, 'shutdown': self.handle_output, 'is_shutdown': self.handle_output } @@ -57,13 +57,30 @@ class SerialReader: except: logging.exception("Exception in serial callback") def connect(self): + # Initial connection logging.info("Starting serial connect") self.ser = serial.Serial(self.serialport, self.baud, timeout=0) stk500v2_leave(self.ser, self.reactor) self.serialqueue = self.ffi_lib.serialqueue_alloc(self.ser.fileno(), 0) - SerialBootStrap(self) self.background_thread = threading.Thread(target=self._bg_thread) self.background_thread.start() + # Obtain and load the data dictionary from the firmware + sbs = SerialBootStrap(self) + identify_data = sbs.get_identify_data() + msgparser = msgproto.MessageParser() + msgparser.process_identify(identify_data) + self.msgparser = msgparser + self.register_callback(self.handle_unknown, '#unknown') + logging.info("Loaded %d commands (%s)" % ( + len(msgparser.messages_by_id), msgparser.version)) + # Setup for runtime + mcu_baud = float(msgparser.config.get('SERIAL_BAUD', 0.)) + if mcu_baud: + baud_adjust = self.BITS_PER_BYTE / mcu_baud + self.ffi_lib.serialqueue_set_baud_adjust( + self.serialqueue, baud_adjust) + get_status = msgparser.lookup_command('get_status') + self.status_cmd = get_status.encode() def connect_file(self, debugoutput, dictionary, pace=False): self.ser = debugoutput self.msgparser.process_identify(dictionary, decompress=False) @@ -184,13 +201,6 @@ class SerialReader: params['#msgid'], repr(params['#msg']))) def handle_output(self, params): logging.info("%s: %s" % (params['#name'], params['#msg'])) - def handle_state(self, params): - state = params['#state'] - if state == 'connected': - logging.info("Loaded %d commands (%s)" % ( - len(self.msgparser.messages_by_id), self.msgparser.version)) - else: - logging.info("State: %s" % (state,)) def handle_default(self, params): logging.warn("got %s" % (params,)) @@ -230,36 +240,25 @@ class SerialBootStrap: self.serial.register_callback(self.handle_unknown, '#unknown') self.send_timer = self.serial.reactor.register_timer( self.send_event, self.serial.reactor.NOW) - def finalize(self): - self.is_done = True - self.serial.msgparser.process_identify(self.identify_data) - logging.info("MCU version: %s" % (self.serial.msgparser.version,)) + def get_identify_data(self): + eventtime = time.time() + while not self.is_done: + eventtime = self.serial.reactor.pause(eventtime + 0.05) self.serial.unregister_callback('identify_response') - self.serial.register_callback(self.serial.handle_unknown, '#unknown') - mcu_baud = float(self.serial.msgparser.config.get('SERIAL_BAUD', 0.)) - if mcu_baud: - baud_adjust = self.serial.BITS_PER_BYTE / mcu_baud - self.serial.ffi_lib.serialqueue_set_baud_adjust( - self.serial.serialqueue, baud_adjust) - get_status = self.serial.msgparser.lookup_command('get_status') - self.serial.status_cmd = get_status.encode() - with self.serial.lock: - hdl = self.serial.handlers['#state', None] - statemsg = {'#name': '#state', '#state': 'connected'} - hdl(statemsg) + self.serial.reactor.unregister_timer(self.send_timer) + return self.identify_data def handle_identify(self, params): if self.is_done or params['offset'] != len(self.identify_data): return msgdata = params['data'] if not msgdata: - self.finalize() + self.is_done = True return self.identify_data += msgdata imsg = self.identify_cmd.encode(len(self.identify_data), 40) self.serial.send(imsg) def send_event(self, eventtime): if self.is_done: - self.serial.reactor.unregister_timer(self.send_timer) return self.serial.reactor.NEVER imsg = self.identify_cmd.encode(len(self.identify_data), 40) self.serial.send(imsg)