aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorKevin O'Connor <kevin@koconnor.net>2021-01-30 00:01:23 -0500
committerKevin O'Connor <kevin@koconnor.net>2021-03-02 11:38:50 -0500
commit9d3a3f3f306af5f1fbd39e537e10392f03f5b27d (patch)
treef4c5a0ae1c9504fe473af069eab82a167db876f6
parentbc2096f543cd437591de7d038911c6c1139b5bd5 (diff)
downloadkutter-9d3a3f3f306af5f1fbd39e537e10392f03f5b27d.tar.gz
kutter-9d3a3f3f306af5f1fbd39e537e10392f03f5b27d.tar.xz
kutter-9d3a3f3f306af5f1fbd39e537e10392f03f5b27d.zip
serialhdl: Update callers to decide serial fd type
Don't try to detect a "real serial port" in serialhdl.py. Instead, have the callers invoke either connect_uart(), connect_file(), or connect_pipe(). Signed-off-by: Kevin O'Connor <kevin@koconnor.net>
-rwxr-xr-xklippy/console.py14
-rw-r--r--klippy/mcu.py34
-rw-r--r--klippy/serialhdl.py105
-rw-r--r--scripts/spi_flash/spi_flash.py6
4 files changed, 89 insertions, 70 deletions
diff --git a/klippy/console.py b/klippy/console.py
index b787111f..ab501d9a 100755
--- a/klippy/console.py
+++ b/klippy/console.py
@@ -30,8 +30,10 @@ help_txt = """
re_eval = re.compile(r'\{(?P<eval>[^}]*)\}')
class KeyboardReader:
- def __init__(self, ser, reactor):
- self.ser = ser
+ def __init__(self, reactor, serialport, baud):
+ self.serialport = serialport
+ self.baud = baud
+ self.ser = serialhdl.SerialReader(reactor)
self.reactor = reactor
self.start_time = reactor.monotonic()
self.clocksync = clocksync.ClockSync(self.reactor)
@@ -52,7 +54,10 @@ class KeyboardReader:
def connect(self, eventtime):
self.output(help_txt)
self.output("="*20 + " attempting to connect " + "="*20)
- self.ser.connect()
+ if self.baud:
+ self.ser.connect_uart(self.serialport, self.baud)
+ else:
+ self.ser.connect_pipe(self.serialport)
msgparser = self.ser.get_msgparser()
message_count = len(msgparser.get_messages())
version, build_versions = msgparser.get_version_info()
@@ -205,8 +210,7 @@ def main():
logging.basicConfig(level=logging.DEBUG)
r = reactor.Reactor()
- ser = serialhdl.SerialReader(r, serialport, baud)
- kbd = KeyboardReader(ser, r)
+ kbd = KeyboardReader(r, serialport, baud)
try:
r.run()
except KeyboardInterrupt:
diff --git a/klippy/mcu.py b/klippy/mcu.py
index fe540962..7c6529a2 100644
--- a/klippy/mcu.py
+++ b/klippy/mcu.py
@@ -410,24 +410,18 @@ class MCU:
self._name = self._name[4:]
# Serial port
self._serialport = config.get('serial')
- serial_rts = True
- if config.get('restart_method', None) == "cheetah":
- # Special case: Cheetah boards require RTS to be deasserted, else
- # a reset will trigger the built-in bootloader.
- serial_rts = False
- baud = 0
+ self._baud = 0
if not (self._serialport.startswith("/dev/rpmsg_")
or self._serialport.startswith("/tmp/klipper_host_")):
- baud = config.getint('baud', 250000, minval=2400)
- self._serial = serialhdl.SerialReader(
- self._reactor, self._serialport, baud, serial_rts)
+ self._baud = config.getint('baud', 250000, minval=2400)
+ self._serial = serialhdl.SerialReader(self._reactor)
# Restarts
+ restart_methods = [None, 'arduino', 'cheetah', 'command', 'rpi_usb']
self._restart_method = 'command'
- if baud:
- rmethods = {m: m for m in [None, 'arduino', 'cheetah', 'command',
- 'rpi_usb']}
- self._restart_method = config.getchoice(
- 'restart_method', rmethods, None)
+ if self._baud:
+ rmethods = {m: m for m in restart_methods}
+ self._restart_method = config.getchoice('restart_method',
+ rmethods, None)
self._reset_cmd = self._config_reset_cmd = None
self._emergency_stop_cmd = None
self._is_shutdown = self._is_timeout = False
@@ -612,12 +606,18 @@ class MCU:
if self.is_fileoutput():
self._connect_file()
else:
- if (self._restart_method == 'rpi_usb'
- and not os.path.exists(self._serialport)):
+ resmeth = self._restart_method
+ if resmeth == 'rpi_usb' and not os.path.exists(self._serialport):
# Try toggling usb power
self._check_restart("enable power")
try:
- self._serial.connect()
+ if self._baud:
+ # Cheetah boards require RTS to be deasserted
+ # else a reset will trigger the built-in bootloader.
+ rts = (resmeth != "cheetah")
+ self._serial.connect_uart(self._serialport, self._baud, rts)
+ else:
+ self._serial.connect_pipe(self._serialport)
self._clocksync.connect(self._serial)
except serialhdl.error as e:
raise error(str(e))
diff --git a/klippy/serialhdl.py b/klippy/serialhdl.py
index 9ef39dfd..c9eccb50 100644
--- a/klippy/serialhdl.py
+++ b/klippy/serialhdl.py
@@ -1,6 +1,6 @@
# Serial port management for firmware communication
#
-# Copyright (C) 2016-2020 Kevin O'Connor <kevin@koconnor.net>
+# Copyright (C) 2016-2021 Kevin O'Connor <kevin@koconnor.net>
#
# This file may be distributed under the terms of the GNU GPLv3 license.
import logging, threading, os
@@ -13,13 +13,10 @@ class error(Exception):
class SerialReader:
BITS_PER_BYTE = 10.
- def __init__(self, reactor, serialport, baud, rts=True):
+ def __init__(self, reactor):
self.reactor = reactor
- self.serialport = serialport
- self.baud = baud
# Serial port
- self.ser = None
- self.rts = rts
+ self.serial_dev = None
self.msgparser = msgproto.MessageParser()
# C interface
self.ffi_main, self.ffi_lib = chelper.get_ffi()
@@ -75,42 +72,20 @@ class SerialReader:
# Done
return identify_data
identify_data += msgdata
- def connect(self):
- # Initial connection
- logging.info("Starting serial connect")
- start_time = self.reactor.monotonic()
- while 1:
- connect_time = self.reactor.monotonic()
- if connect_time > start_time + 90.:
- raise error("Unable to connect")
- try:
- if self.baud:
- self.ser = serial.Serial(
- baudrate=self.baud, timeout=0, exclusive=True)
- self.ser.port = self.serialport
- self.ser.rts = self.rts
- self.ser.open()
- else:
- fd = os.open(self.serialport, os.O_RDWR | os.O_NOCTTY)
- self.ser = os.fdopen(fd, 'rb+', 0)
- except (OSError, IOError, serial.SerialException) as e:
- logging.warn("Unable to open port: %s", e)
- self.reactor.pause(connect_time + 5.)
- continue
- if self.baud:
- stk500v2_leave(self.ser, self.reactor)
- self.serialqueue = self.ffi_main.gc(
- self.ffi_lib.serialqueue_alloc(self.ser.fileno(), 0),
- self.ffi_lib.serialqueue_free)
- self.background_thread = threading.Thread(target=self._bg_thread)
- self.background_thread.start()
- # Obtain and load the data dictionary from the firmware
- completion = self.reactor.register_callback(self._get_identify_data)
- identify_data = completion.wait(connect_time + 5.)
- if identify_data is not None:
- break
- logging.info("Timeout on serial connect")
+ def _start_session(self, serial_dev):
+ self.serial_dev = serial_dev
+ self.serialqueue = self.ffi_main.gc(
+ self.ffi_lib.serialqueue_alloc(serial_dev.fileno(), 0),
+ self.ffi_lib.serialqueue_free)
+ self.background_thread = threading.Thread(target=self._bg_thread)
+ self.background_thread.start()
+ # Obtain and load the data dictionary from the firmware
+ completion = self.reactor.register_callback(self._get_identify_data)
+ identify_data = completion.wait(self.reactor.monotonic() + 5.)
+ if identify_data is None:
+ logging.info("Timeout on connect")
self.disconnect()
+ return False
msgparser = msgproto.MessageParser()
msgparser.process_identify(identify_data)
self.msgparser = msgparser
@@ -125,11 +100,49 @@ class SerialReader:
if receive_window is not None:
self.ffi_lib.serialqueue_set_receive_window(
self.serialqueue, receive_window)
+ return True
+ def connect_pipe(self, filename):
+ logging.info("Starting connect")
+ start_time = self.reactor.monotonic()
+ while 1:
+ if self.reactor.monotonic() > start_time + 90.:
+ raise error("Unable to connect")
+ try:
+ fd = os.open(filename, os.O_RDWR | os.O_NOCTTY)
+ except OSError as e:
+ logging.warn("Unable to open port: %s", e)
+ self.reactor.pause(self.reactor.monotonic() + 5.)
+ continue
+ serial_dev = os.fdopen(fd, 'rb+', 0)
+ ret = self._start_session(serial_dev)
+ if ret:
+ break
+ def connect_uart(self, serialport, baud, rts=True):
+ # Initial connection
+ logging.info("Starting serial connect")
+ start_time = self.reactor.monotonic()
+ while 1:
+ if self.reactor.monotonic() > start_time + 90.:
+ raise error("Unable to connect")
+ try:
+ serial_dev = serial.Serial(baudrate=baud, timeout=0,
+ exclusive=True)
+ serial_dev.port = serialport
+ serial_dev.rts = rts
+ serial_dev.open()
+ except (OSError, IOError, serial.SerialException) as e:
+ logging.warn("Unable to open serial port: %s", e)
+ self.reactor.pause(self.reactor.monotonic() + 5.)
+ continue
+ stk500v2_leave(serial_dev, self.reactor)
+ ret = self._start_session(serial_dev)
+ if ret:
+ break
def connect_file(self, debugoutput, dictionary, pace=False):
- self.ser = debugoutput
+ self.serial_dev = debugoutput
self.msgparser.process_identify(dictionary, decompress=False)
self.serialqueue = self.ffi_main.gc(
- self.ffi_lib.serialqueue_alloc(self.ser.fileno(), 1),
+ self.ffi_lib.serialqueue_alloc(self.serial_dev.fileno(), 1),
self.ffi_lib.serialqueue_free)
def set_clock_est(self, freq, last_time, last_clock):
self.ffi_lib.serialqueue_set_clock_est(
@@ -140,9 +153,9 @@ class SerialReader:
if self.background_thread is not None:
self.background_thread.join()
self.background_thread = self.serialqueue = None
- if self.ser is not None:
- self.ser.close()
- self.ser = None
+ if self.serial_dev is not None:
+ self.serial_dev.close()
+ self.serial_dev = None
for pn in self.pending_notifications.values():
pn.complete(None)
self.pending_notifications.clear()
diff --git a/scripts/spi_flash/spi_flash.py b/scripts/spi_flash/spi_flash.py
index 5376dc2d..137adf5a 100644
--- a/scripts/spi_flash/spi_flash.py
+++ b/scripts/spi_flash/spi_flash.py
@@ -777,9 +777,11 @@ class SDCardSPI:
class MCUConnection:
def __init__(self, k_reactor, device, baud, board_cfg):
self.reactor = k_reactor
+ self.serial_device = device
+ self.baud = baud
# TODO: a change in baudrate will cause an issue, come up
# with a method for handling it gracefully
- self._serial = serialhdl.SerialReader(self.reactor, device, baud)
+ self._serial = serialhdl.SerialReader(self.reactor)
self.clocksync = clocksync.ClockSync(self.reactor)
self.board_config = board_cfg
self.fatfs = None
@@ -817,7 +819,7 @@ class MCUConnection:
endtime = eventtime + 60.
while True:
try:
- self._serial.connect()
+ self._serial.connect_uart(self.serial_device, self.baud)
self.clocksync.connect(self._serial)
except Exception:
curtime = self.reactor.monotonic()