aboutsummaryrefslogtreecommitdiffstats
path: root/klippy
diff options
context:
space:
mode:
authorGrigori Goronzy <greg@chown.ath.cx>2020-04-01 23:52:55 +0200
committerKevinOConnor <kevin@koconnor.net>2020-04-02 13:56:50 -0400
commit0a20430e07801a277e2fc37de30035730d1084f2 (patch)
treed029b09c5d054f45aa479f1a446310d76bee5a7a /klippy
parent5c8d15bbee9b1c4c82e3a2ecb5c63ce37f4a8dcb (diff)
downloadkutter-0a20430e07801a277e2fc37de30035730d1084f2.tar.gz
kutter-0a20430e07801a277e2fc37de30035730d1084f2.tar.xz
kutter-0a20430e07801a277e2fc37de30035730d1084f2.zip
serial: Add Fysetc Cheetah board specific reset sequence
Fysetc Cheetah v1.2 boards require a special sequence to reset reliably. This sequence works for me in all cases. Simpler sequences without double reset did not work correctly. This is likely because of a weird stateful circuitry for toggling the bootloader state. Cheetah boards use RTS to configure bootloader triggering. By default, pySerial sets RTS on connect, which unfortunately configures the board to start the bootloader on reset. Add a toggle for the RTS state to allow users to workaround. The RTS state is set before the serial connection is opened, so there are no glitches. Addresses #2026. Signed-off-by: Grigori Goronzy <greg@chown.ath.cx>
Diffstat (limited to 'klippy')
-rw-r--r--klippy/mcu.py16
-rw-r--r--klippy/serialhdl.py34
2 files changed, 46 insertions, 4 deletions
diff --git a/klippy/mcu.py b/klippy/mcu.py
index 49ec6cb0..36e9c48d 100644
--- a/klippy/mcu.py
+++ b/klippy/mcu.py
@@ -386,16 +386,22 @@ class MCU:
self._disconnect)
# Serial port
self._serialport = config.get('serial', '/dev/ttyS0')
+ 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
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)
+ self._reactor, self._serialport, baud, serial_rts)
# Restarts
self._restart_method = 'command'
if baud:
- rmethods = {m: m for m in [None, 'arduino', 'command', 'rpi_usb']}
+ rmethods = {m: m for m in [None, 'arduino', 'cheetah', 'command',
+ 'rpi_usb']}
self._restart_method = config.getchoice(
'restart_method', rmethods, None)
self._reset_cmd = self._config_reset_cmd = None
@@ -683,6 +689,10 @@ class MCU:
logging.info("Attempting MCU '%s' reset", self._name)
self._disconnect()
serialhdl.arduino_reset(self._serialport, self._reactor)
+ def _restart_cheetah(self):
+ logging.info("Attempting MCU '%s' Cheetah-style reset", self._name)
+ self._disconnect()
+ serialhdl.cheetah_reset(self._serialport, self._reactor)
def _restart_via_command(self):
if ((self._reset_cmd is None and self._config_reset_cmd is None)
or not self._clocksync.is_active()):
@@ -713,6 +723,8 @@ class MCU:
self._restart_rpi_usb()
elif self._restart_method == 'command':
self._restart_via_command()
+ elif self._restart_method == 'cheetah':
+ self._restart_cheetah()
else:
self._restart_arduino()
# Misc external commands
diff --git a/klippy/serialhdl.py b/klippy/serialhdl.py
index bc8a9d3c..46e31ed4 100644
--- a/klippy/serialhdl.py
+++ b/klippy/serialhdl.py
@@ -13,12 +13,13 @@ class error(Exception):
class SerialReader:
BITS_PER_BYTE = 10.
- def __init__(self, reactor, serialport, baud):
+ def __init__(self, reactor, serialport, baud, rts=True):
self.reactor = reactor
self.serialport = serialport
self.baud = baud
# Serial port
self.ser = None
+ self.rts = rts
self.msgparser = msgproto.MessageParser()
# C interface
self.ffi_main, self.ffi_lib = chelper.get_ffi()
@@ -85,7 +86,10 @@ class SerialReader:
try:
if self.baud:
self.ser = serial.Serial(
- self.serialport, self.baud, timeout=0, exclusive=True)
+ baudrate=self.baud, timeout=0, exclusive=True)
+ self.ser.port = self.serialport
+ self.ser.rts = self.rts
+ self.ser.open()
else:
self.ser = open(self.serialport, 'rb+')
except (OSError, IOError, serial.SerialException) as e:
@@ -266,6 +270,32 @@ def stk500v2_leave(ser, reactor):
logging.debug("Got %s from stk500v2", repr(res))
ser.baudrate = origbaud
+def cheetah_reset(serialport, reactor):
+ # Fysetc Cheetah v1.2 boards have a weird stateful circuitry for
+ # configuring the bootloader. This sequence takes care of disabling it for
+ # sure.
+ # Open the serial port with RTS asserted
+ ser = serial.Serial(baudrate=2400, timeout=0, exclusive=True)
+ ser.port = serialport
+ ser.rts = True
+ ser.open()
+ ser.read(1)
+ reactor.pause(reactor.monotonic() + 0.100)
+ # Toggle DTR
+ ser.dtr = True
+ reactor.pause(reactor.monotonic() + 0.100)
+ ser.dtr = False
+ # Deassert RTS
+ reactor.pause(reactor.monotonic() + 0.100)
+ ser.rts = False
+ reactor.pause(reactor.monotonic() + 0.100)
+ # Toggle DTR again
+ ser.dtr = True
+ reactor.pause(reactor.monotonic() + 0.100)
+ ser.dtr = False
+ reactor.pause(reactor.monotonic() + 0.100)
+ ser.close()
+
# Attempt an arduino style reset on a serial port
def arduino_reset(serialport, reactor):
# First try opening the port at a different baud