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 <kevin@koconnor.net>
This commit is contained in:
parent
5d805ba550
commit
535c7b99b4
|
@ -18,9 +18,14 @@ class KeyboardReader:
|
||||||
util.set_nonblock(self.fd)
|
util.set_nonblock(self.fd)
|
||||||
self.pins = None
|
self.pins = None
|
||||||
self.data = ""
|
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.local_commands = { "PINS": self.set_pin_map, "SET": self.set_var }
|
||||||
self.eval_globals = {}
|
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):
|
def update_evals(self, eventtime):
|
||||||
f = self.ser.msgparser.config.get('CLOCK_FREQ', 1)
|
f = self.ser.msgparser.config.get('CLOCK_FREQ', 1)
|
||||||
c = self.ser.get_clock(eventtime)
|
c = self.ser.get_clock(eventtime)
|
||||||
|
@ -101,7 +106,6 @@ def main():
|
||||||
logging.basicConfig(level=logging.DEBUG)
|
logging.basicConfig(level=logging.DEBUG)
|
||||||
r = reactor.Reactor()
|
r = reactor.Reactor()
|
||||||
ser = serialhdl.SerialReader(r, serialport, baud)
|
ser = serialhdl.SerialReader(r, serialport, baud)
|
||||||
ser.connect()
|
|
||||||
kbd = KeyboardReader(ser, r)
|
kbd = KeyboardReader(ser, r)
|
||||||
try:
|
try:
|
||||||
r.run()
|
r.run()
|
||||||
|
|
|
@ -85,9 +85,6 @@ class Printer:
|
||||||
def connect_file(self, output, dictionary):
|
def connect_file(self, output, dictionary):
|
||||||
self.reactor.update_timer(self.stats_timer, self.reactor.NEVER)
|
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.gcode.run()
|
|
||||||
self.reactor.unregister_timer(self.connect_timer)
|
|
||||||
def run(self):
|
def run(self):
|
||||||
self.reactor.run()
|
self.reactor.run()
|
||||||
# If gcode exits, then exit the MCU
|
# If gcode exits, then exit the MCU
|
||||||
|
|
|
@ -342,15 +342,8 @@ 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 = {}
|
if not self._is_fileoutput:
|
||||||
def handle_serial_state(params):
|
self.serial.connect()
|
||||||
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")
|
|
||||||
self._mcu_freq = float(self.serial.msgparser.config['CLOCK_FREQ'])
|
self._mcu_freq = float(self.serial.msgparser.config['CLOCK_FREQ'])
|
||||||
self.register_msg(self.handle_shutdown, 'shutdown')
|
self.register_msg(self.handle_shutdown, 'shutdown')
|
||||||
self.register_msg(self.handle_shutdown, 'is_shutdown')
|
self.register_msg(self.handle_shutdown, 'is_shutdown')
|
||||||
|
@ -358,7 +351,6 @@ class MCU:
|
||||||
def connect_file(self, debugoutput, dictionary, pace=False):
|
def connect_file(self, debugoutput, dictionary, pace=False):
|
||||||
self._is_fileoutput = True
|
self._is_fileoutput = True
|
||||||
self.serial.connect_file(debugoutput, dictionary)
|
self.serial.connect_file(debugoutput, dictionary)
|
||||||
self._mcu_freq = float(self.serial.msgparser.config['CLOCK_FREQ'])
|
|
||||||
def dummy_send_config():
|
def dummy_send_config():
|
||||||
for c in self._config_cmds:
|
for c in self._config_cmds:
|
||||||
self.send(self.create_command(c))
|
self.send(self.create_command(c))
|
||||||
|
|
|
@ -34,7 +34,7 @@ class SerialReader:
|
||||||
self._status_event, self.reactor.NOW)
|
self._status_event, self.reactor.NOW)
|
||||||
self.status_cmd = None
|
self.status_cmd = None
|
||||||
handlers = {
|
handlers = {
|
||||||
'#unknown': self.handle_unknown, '#state': self.handle_state,
|
'#unknown': self.handle_unknown,
|
||||||
'#output': self.handle_output, 'status': self.handle_status,
|
'#output': self.handle_output, 'status': self.handle_status,
|
||||||
'shutdown': self.handle_output, 'is_shutdown': self.handle_output
|
'shutdown': self.handle_output, 'is_shutdown': self.handle_output
|
||||||
}
|
}
|
||||||
|
@ -57,13 +57,30 @@ class SerialReader:
|
||||||
except:
|
except:
|
||||||
logging.exception("Exception in serial callback")
|
logging.exception("Exception in serial callback")
|
||||||
def connect(self):
|
def connect(self):
|
||||||
|
# Initial connection
|
||||||
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, self.reactor)
|
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)
|
|
||||||
self.background_thread = threading.Thread(target=self._bg_thread)
|
self.background_thread = threading.Thread(target=self._bg_thread)
|
||||||
self.background_thread.start()
|
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):
|
def connect_file(self, debugoutput, dictionary, pace=False):
|
||||||
self.ser = debugoutput
|
self.ser = debugoutput
|
||||||
self.msgparser.process_identify(dictionary, decompress=False)
|
self.msgparser.process_identify(dictionary, decompress=False)
|
||||||
|
@ -184,13 +201,6 @@ class SerialReader:
|
||||||
params['#msgid'], repr(params['#msg'])))
|
params['#msgid'], repr(params['#msg'])))
|
||||||
def handle_output(self, params):
|
def handle_output(self, params):
|
||||||
logging.info("%s: %s" % (params['#name'], params['#msg']))
|
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):
|
def handle_default(self, params):
|
||||||
logging.warn("got %s" % (params,))
|
logging.warn("got %s" % (params,))
|
||||||
|
|
||||||
|
@ -230,36 +240,25 @@ class SerialBootStrap:
|
||||||
self.serial.register_callback(self.handle_unknown, '#unknown')
|
self.serial.register_callback(self.handle_unknown, '#unknown')
|
||||||
self.send_timer = self.serial.reactor.register_timer(
|
self.send_timer = self.serial.reactor.register_timer(
|
||||||
self.send_event, self.serial.reactor.NOW)
|
self.send_event, self.serial.reactor.NOW)
|
||||||
def finalize(self):
|
def get_identify_data(self):
|
||||||
self.is_done = True
|
eventtime = time.time()
|
||||||
self.serial.msgparser.process_identify(self.identify_data)
|
while not self.is_done:
|
||||||
logging.info("MCU version: %s" % (self.serial.msgparser.version,))
|
eventtime = self.serial.reactor.pause(eventtime + 0.05)
|
||||||
self.serial.unregister_callback('identify_response')
|
self.serial.unregister_callback('identify_response')
|
||||||
self.serial.register_callback(self.serial.handle_unknown, '#unknown')
|
self.serial.reactor.unregister_timer(self.send_timer)
|
||||||
mcu_baud = float(self.serial.msgparser.config.get('SERIAL_BAUD', 0.))
|
return self.identify_data
|
||||||
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)
|
|
||||||
def handle_identify(self, params):
|
def handle_identify(self, params):
|
||||||
if self.is_done or params['offset'] != len(self.identify_data):
|
if self.is_done or params['offset'] != len(self.identify_data):
|
||||||
return
|
return
|
||||||
msgdata = params['data']
|
msgdata = params['data']
|
||||||
if not msgdata:
|
if not msgdata:
|
||||||
self.finalize()
|
self.is_done = True
|
||||||
return
|
return
|
||||||
self.identify_data += msgdata
|
self.identify_data += msgdata
|
||||||
imsg = self.identify_cmd.encode(len(self.identify_data), 40)
|
imsg = self.identify_cmd.encode(len(self.identify_data), 40)
|
||||||
self.serial.send(imsg)
|
self.serial.send(imsg)
|
||||||
def send_event(self, eventtime):
|
def send_event(self, eventtime):
|
||||||
if self.is_done:
|
if self.is_done:
|
||||||
self.serial.reactor.unregister_timer(self.send_timer)
|
|
||||||
return self.serial.reactor.NEVER
|
return self.serial.reactor.NEVER
|
||||||
imsg = self.identify_cmd.encode(len(self.identify_data), 40)
|
imsg = self.identify_cmd.encode(len(self.identify_data), 40)
|
||||||
self.serial.send(imsg)
|
self.serial.send(imsg)
|
||||||
|
|
Loading…
Reference in New Issue