aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--config/example.cfg19
-rw-r--r--klippy/mcu.py16
-rw-r--r--klippy/serialhdl.py34
3 files changed, 56 insertions, 13 deletions
diff --git a/config/example.cfg b/config/example.cfg
index c579864e..b93dda6f 100644
--- a/config/example.cfg
+++ b/config/example.cfg
@@ -288,15 +288,16 @@ pin_map: arduino
# default is to not enable the aliases.
#restart_method:
# This controls the mechanism the host will use to reset the
-# micro-controller. The choices are 'arduino', 'rpi_usb', and
-# 'command'. The 'arduino' method (toggle DTR) is common on Arduino
-# boards and clones. The 'rpi_usb' method is useful on Raspberry Pi
-# boards with micro-controllers powered over USB - it briefly
-# disables power to all USB ports to accomplish a micro-controller
-# reset. The 'command' method involves sending a Klipper command to
-# the micro-controller so that it can reset itself. The default is
-# 'arduino' if the micro-controller communicates over a serial port,
-# 'command' otherwise.
+# micro-controller. The choices are 'arduino', 'cheetah', 'rpi_usb',
+# and 'command'. The 'arduino' method (toggle DTR) is common on
+# Arduino boards and clones. The 'cheetah' method is a special
+# method needed for some Fysetc Cheetah boards. The 'rpi_usb' method
+# is useful on Raspberry Pi boards with micro-controllers powered
+# over USB - it briefly disables power to all USB ports to
+# accomplish a micro-controller reset. The 'command' method involves
+# sending a Klipper command to the micro-controller so that it can
+# reset itself. The default is 'arduino' if the micro-controller
+# communicates over a serial port, 'command' otherwise.
# The printer section controls high level printer settings.
[printer]
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