diff options
author | Kevin O'Connor <kevin@koconnor.net> | 2017-04-13 12:09:37 -0400 |
---|---|---|
committer | Kevin O'Connor <kevin@koconnor.net> | 2017-04-13 13:20:13 -0400 |
commit | daff83ee9a7366c23470a78d30d20df3881293c0 (patch) | |
tree | 5e421031dd795b2004bc4bc839f05b7eacfc4c52 /klippy | |
parent | 9f9e3e61d60c4d5e377bff1ce0128294a864cfc3 (diff) | |
download | kutter-daff83ee9a7366c23470a78d30d20df3881293c0.tar.gz kutter-daff83ee9a7366c23470a78d30d20df3881293c0.tar.xz kutter-daff83ee9a7366c23470a78d30d20df3881293c0.zip |
hub-ctrl: Add support for micro-controller reset via RPi usb power toggling
Signed-off-by: Kevin O'Connor <kevin@koconnor.net>
Diffstat (limited to 'klippy')
-rw-r--r-- | klippy/chelper.py | 41 | ||||
-rw-r--r-- | klippy/mcu.py | 34 |
2 files changed, 57 insertions, 18 deletions
diff --git a/klippy/chelper.py b/klippy/chelper.py index b05bc74c..7b4b510a 100644 --- a/klippy/chelper.py +++ b/klippy/chelper.py @@ -1,11 +1,16 @@ # Wrapper around C helper code # -# Copyright (C) 2016 Kevin O'Connor <kevin@koconnor.net> +# Copyright (C) 2016,2017 Kevin O'Connor <kevin@koconnor.net> # # This file may be distributed under the terms of the GNU GPLv3 license. import os, logging import cffi + +###################################################################### +# c_helper.so compiling +###################################################################### + COMPILE_CMD = "gcc -Wall -g -O2 -shared -fPIC -o %s %s" SOURCE_FILES = ['stepcompress.c', 'serialqueue.c', 'pyhelper.c'] DEST_LIB = "c_helper.so" @@ -79,14 +84,14 @@ def get_mtimes(srcdir, filelist): return out # Check if the code needs to be compiled -def check_build_code(srcdir): - src_times = get_mtimes(srcdir, SOURCE_FILES + OTHER_FILES) - obj_times = get_mtimes(srcdir, [DEST_LIB]) +def check_build_code(srcdir, target, sources, cmd, other_files=[]): + src_times = get_mtimes(srcdir, sources + other_files) + obj_times = get_mtimes(srcdir, [target]) if not obj_times or max(src_times) > min(obj_times): - logging.info("Building C code module") - srcfiles = [os.path.join(srcdir, fname) for fname in SOURCE_FILES] - destlib = os.path.join(srcdir, DEST_LIB) - os.system(COMPILE_CMD % (destlib, ' '.join(srcfiles))) + logging.info("Building C code module %s" % (target,)) + srcfiles = [os.path.join(srcdir, fname) for fname in sources] + destlib = os.path.join(srcdir, target) + os.system(cmd % (destlib, ' '.join(srcfiles))) FFI_main = None FFI_lib = None @@ -97,7 +102,8 @@ def get_ffi(): global FFI_main, FFI_lib, pyhelper_logging_callback if FFI_lib is None: srcdir = os.path.dirname(os.path.realpath(__file__)) - check_build_code(srcdir) + check_build_code(srcdir, DEST_LIB, SOURCE_FILES, COMPILE_CMD + , OTHER_FILES) FFI_main = cffi.FFI() FFI_main.cdef(defs_stepcompress) FFI_main.cdef(defs_serialqueue) @@ -110,3 +116,20 @@ def get_ffi(): "void(const char *)", logging_callback) FFI_lib.set_python_logging_callback(pyhelper_logging_callback) return FFI_main, FFI_lib + + +###################################################################### +# hub-ctrl hub power controller +###################################################################### + +HC_COMPILE_CMD = "gcc -Wall -g -O2 -o %s %s -lusb" +HC_SOURCE_FILES = ['hub-ctrl.c'] +HC_SOURCE_DIR = '../lib/hub-ctrl' +HC_TARGET = "hub-ctrl" +HC_CMD = "sudo %s/hub-ctrl -h 0 -P 2 -p %d" + +def run_hub_ctrl(enable_power): + srcdir = os.path.dirname(os.path.realpath(__file__)) + hubdir = os.path.join(srcdir, HC_SOURCE_DIR) + check_build_code(hubdir, HC_TARGET, HC_SOURCE_FILES, HC_COMPILE_CMD) + os.system(HC_CMD % (hubdir, enable_power)) diff --git a/klippy/mcu.py b/klippy/mcu.py index 4601e769..0f97205d 100644 --- a/klippy/mcu.py +++ b/klippy/mcu.py @@ -1,9 +1,9 @@ # Multi-processor safe interface to micro-controller # -# Copyright (C) 2016 Kevin O'Connor <kevin@koconnor.net> +# Copyright (C) 2016,2017 Kevin O'Connor <kevin@koconnor.net> # # This file may be distributed under the terms of the GNU GPLv3 license. -import sys, zlib, logging, math +import sys, os, zlib, logging, math import serialhdl, pins, chelper class error(Exception): @@ -381,7 +381,7 @@ class MCU: self._is_fileoutput = False self._timeout_timer = printer.reactor.register_timer( self.timeout_handler) - rmethods = {m: m for m in ['arduino', 'command']} + rmethods = {m: m for m in ['arduino', 'command', 'rpi_usb']} self._restart_method = config.getchoice( 'restart_method', rmethods, 'arduino') # Config building @@ -424,8 +424,19 @@ class MCU: self.serial.dump_debug() self._printer.note_shutdown(self._shutdown_msg) # Connection phase + def _check_restart(self, reason): + if self._printer.get_startup_state() == 'firmware_restart': + return + logging.info("Attempting automated firmware restart: %s" % (reason,)) + self._printer.request_exit('firmware_restart') + self._printer.reactor.pause(self._printer.reactor.monotonic() + 2.000) + raise error("Attempt firmware restart failed") def connect(self): if not self._is_fileoutput: + if (self._restart_method == 'rpi_usb' + and not os.path.exists(self._serialport)): + # Try toggling usb power + self._check_restart("enable power") self.serial.connect() self._printer.reactor.update_timer( self._timeout_timer, self.monotonic() + self.COMM_TIMEOUT) @@ -478,6 +489,13 @@ class MCU: self.send(self._clear_shutdown_cmd.encode()) def microcontroller_restart(self): reactor = self._printer.reactor + if self._restart_method == 'rpi_usb': + logging.info("Attempting a microcontroller reset via rpi usb power") + self.disconnect() + chelper.run_hub_ctrl(0) + reactor.pause(reactor.monotonic() + 2.000) + chelper.run_hub_ctrl(1) + return if self._restart_method == 'command': last_clock, last_clock_time = self.serial.get_last_clock() eventtime = reactor.monotonic() @@ -539,6 +557,9 @@ class MCU: else: config_params = self.serial.send_with_response(msg, 'config') if not config_params['is_config']: + if self._restart_method == 'rpi_usb': + # Only configure mcu after usb power reset + self._check_restart("full reset before config") # Send config commands logging.info("Sending printer configuration...") for c in self._config_cmds: @@ -551,12 +572,7 @@ class MCU: self._shutdown_msg,)) raise error("Unable to configure printer") if self._config_crc != config_params['crc']: - if self._printer.get_startup_state() != 'firmware_restart': - # Attempt a firmware restart to fix the CRC error - logging.info( - "Printer CRC mismatch - attempting firmware restart") - self._printer.request_exit('firmware_restart') - self._printer.reactor.pause(0.100) + self._check_restart("CRC mismatch") raise error("Printer CRC does not match config") move_count = config_params['move_count'] logging.info("Configured (%d moves)" % (move_count,)) |