klippy: Run the MCU connect code within the reactor

Setup the reactor and run the MCU connection code as a timer within
the reactor.  The connection code will make use of reactor greenlets
so that it can wait for events during the connection phase.

Signed-off-by: Kevin O'Connor <kevin@koconnor.net>
This commit is contained in:
Kevin O'Connor 2016-11-28 13:14:56 -05:00
parent bafe796eeb
commit 5d805ba550
4 changed files with 28 additions and 24 deletions

View File

@ -59,7 +59,6 @@ class GCodeParser:
for h in handlers) for h in handlers)
def run(self): def run(self):
self.fd_handle = self.reactor.register_fd(self.fd, self.process_data) self.fd_handle = self.reactor.register_fd(self.fd, self.process_data)
self.reactor.run()
def finish(self): def finish(self):
self.reactor.end() self.reactor.end()
self.toolhead.motor_off() self.toolhead.motor_off()

View File

@ -45,8 +45,11 @@ class Printer:
self.gcode = gcode.GCodeParser( self.gcode = gcode.GCodeParser(
self, pseudo_tty, inputfile=debuginput is not None) self, pseudo_tty, inputfile=debuginput is not None)
self.mcu = None self.mcu = mcu.MCU(self, ConfigWrapper(self, 'mcu'))
self.stat_timer = None self.stats_timer = self.reactor.register_timer(
self.stats, self.reactor.NOW)
self.connect_timer = self.reactor.register_timer(
self.connect, self.reactor.NOW)
self.objects = {} self.objects = {}
if self.fileconfig.has_section('fan'): if self.fileconfig.has_section('fan'):
@ -73,18 +76,20 @@ class Printer:
self.objects[oname].build_config() self.objects[oname].build_config()
self.gcode.build_config() self.gcode.build_config()
self.mcu.build_config() self.mcu.build_config()
def connect(self): def connect(self, eventtime):
self.mcu = mcu.MCU(self, ConfigWrapper(self, 'mcu'))
self.mcu.connect() self.mcu.connect()
self.build_config() self.build_config()
self.stats_timer = self.reactor.register_timer( self.gcode.run()
self.stats, self.reactor.NOW) self.reactor.unregister_timer(self.connect_timer)
return self.reactor.NEVER
def connect_file(self, output, dictionary): def connect_file(self, output, dictionary):
self.mcu = mcu.MCU(self, ConfigWrapper(self, 'mcu')) self.reactor.update_timer(self.stats_timer, self.reactor.NEVER)
self.mcu.connect_file(output, dictionary) self.mcu.connect_file(output, dictionary)
self.build_config() self.build_config()
def run(self):
self.gcode.run() self.gcode.run()
self.reactor.unregister_timer(self.connect_timer)
def run(self):
self.reactor.run()
# If gcode exits, then exit the MCU # If gcode exits, then exit the MCU
self.stats(time.time()) self.stats(time.time())
self.mcu.disconnect() self.mcu.disconnect()
@ -141,8 +146,6 @@ def main():
if debugoutput: if debugoutput:
proto_dict = read_dictionary(options.read_dictionary) proto_dict = read_dictionary(options.read_dictionary)
printer.connect_file(debugoutput, proto_dict) printer.connect_file(debugoutput, proto_dict)
else:
printer.connect()
printer.run() printer.run()
if bglogger is not None: if bglogger is not None:

View File

@ -342,12 +342,13 @@ class MCU:
self._steppersync = self.ffi_lib.steppersync_alloc( self._steppersync = self.ffi_lib.steppersync_alloc(
self.serial.serialqueue, stepqueues, len(stepqueues), count) self.serial.serialqueue, stepqueues, len(stepqueues), count)
def connect(self): def connect(self):
state_params = {}
def handle_serial_state(params): def handle_serial_state(params):
if params['#state'] == 'connected': state_params.update(params)
self._printer.reactor.end()
self.serial.register_callback(handle_serial_state, '#state') self.serial.register_callback(handle_serial_state, '#state')
self.serial.connect() self.serial.connect()
self._printer.reactor.run() while state_params.get('#state') != 'connected':
self._printer.reactor.pause(time.time() + 0.05)
self.serial.unregister_callback('#state') self.serial.unregister_callback('#state')
logging.info("serial connected") logging.info("serial connected")
self._mcu_freq = float(self.serial.msgparser.config['CLOCK_FREQ']) self._mcu_freq = float(self.serial.msgparser.config['CLOCK_FREQ'])
@ -427,14 +428,15 @@ class MCU:
sent_config = False sent_config = False
def handle_get_config(params): def handle_get_config(params):
config_params.update(params) config_params.update(params)
done = not sent_config or params['is_config'] return True
if done:
self._printer.reactor.end()
return done
while 1: while 1:
self.serial.send_with_response(msg, handle_get_config, 'config') self.serial.send_with_response(msg, handle_get_config, 'config')
self._printer.reactor.run() while 1:
if not config_params['is_config']: 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 # Send config commands
for c in self._config_cmds: for c in self._config_cmds:
self.send(self.create_command(c)) self.send(self.create_command(c))

View File

@ -59,7 +59,7 @@ class SerialReader:
def connect(self): def connect(self):
logging.info("Starting serial connect") logging.info("Starting serial connect")
self.ser = serial.Serial(self.serialport, self.baud, timeout=0) self.ser = serial.Serial(self.serialport, self.baud, timeout=0)
stk500v2_leave(self.ser) stk500v2_leave(self.ser, self.reactor)
self.serialqueue = self.ffi_lib.serialqueue_alloc(self.ser.fileno(), 0) self.serialqueue = self.ffi_lib.serialqueue_alloc(self.ser.fileno(), 0)
SerialBootStrap(self) SerialBootStrap(self)
self.background_thread = threading.Thread(target=self._bg_thread) self.background_thread = threading.Thread(target=self._bg_thread)
@ -269,7 +269,7 @@ class SerialBootStrap:
params['#msgid'], len(params['#msg']))) params['#msgid'], len(params['#msg'])))
# Attempt to place an AVR stk500v2 style programmer into normal mode # Attempt to place an AVR stk500v2 style programmer into normal mode
def stk500v2_leave(ser): def stk500v2_leave(ser, reactor):
logging.debug("Starting stk500v2 leave programmer sequence") logging.debug("Starting stk500v2 leave programmer sequence")
origbaud = ser.baudrate origbaud = ser.baudrate
# Request a dummy speed first as this seems to help reset the port # Request a dummy speed first as this seems to help reset the port
@ -277,10 +277,10 @@ def stk500v2_leave(ser):
ser.read(1) ser.read(1)
# Send stk500v2 leave programmer sequence # Send stk500v2 leave programmer sequence
ser.baudrate = 115200 ser.baudrate = 115200
time.sleep(0.100) reactor.pause(time.time() + 0.100)
ser.read(4096) ser.read(4096)
ser.write('\x1b\x01\x00\x01\x0e\x11\x04') ser.write('\x1b\x01\x00\x01\x0e\x11\x04')
time.sleep(0.050) reactor.pause(time.time() + 0.050)
res = ser.read(4096) res = ser.read(4096)
logging.debug("Got %s from stk500v2" % (repr(res),)) logging.debug("Got %s from stk500v2" % (repr(res),))
ser.baudrate = origbaud ser.baudrate = origbaud