klippy: Warn the user on common errors due to old firmware

Check for msgproto.error and warn the user about version firmware
version mismatch.  Raise msgproto.error when extracting firmware
constants.

Signed-off-by: Kevin O'Connor <kevin@koconnor.net>
This commit is contained in:
Kevin O'Connor 2017-01-09 23:50:13 -05:00
parent eebaeeff96
commit 93d3a6e1d1
3 changed files with 31 additions and 5 deletions

View File

@ -6,6 +6,7 @@
# This file may be distributed under the terms of the GNU GPLv3 license.
import sys, optparse, ConfigParser, logging, time, threading
import gcode, toolhead, util, mcu, fan, heater, extruder, reactor, queuelogger
import msgproto
message_startup = """
The klippy host software is attempting to connect. Please
@ -19,6 +20,15 @@ command to reload the config and restart the host software.
Printer is halted
"""
message_protocol_error = """
This type of error is frequently caused by running an older
version of the firmware on the micro-controller (fix by
recompiling and flashing the firmware).
Once the underlying issue is corrected, use the "RESTART"
command to reload the config and restart the host software.
Protocol error connecting to printer
"""
message_mcu_connect_error = """
This is an unrecoverable error. Please manually restart the
micro-controller and then issue the "RESTART" command to
@ -169,6 +179,10 @@ class Printer:
logging.exception("Config error")
self.state_message = "%s%s" % (str(e), message_restart)
self.reactor.update_timer(self.stats_timer, self.reactor.NEVER)
except msgproto.error, e:
logging.exception("Protocol error")
self.state_message = "%s%s" % (str(e), message_protocol_error)
self.reactor.update_timer(self.stats_timer, self.reactor.NEVER)
except mcu.error, e:
logging.exception("MCU error during connect")
self.state_message = "%s%s" % (str(e), message_mcu_connect_error)

View File

@ -283,7 +283,7 @@ class MCU_adc:
minval = 0
if maxval is None:
maxval = 0xffff
mcu_adc_max = float(self._mcu.serial.msgparser.config["ADC_MAX"])
mcu_adc_max = self._mcu.serial.msgparser.get_constant_float("ADC_MAX")
max_adc = sample_count * mcu_adc_max
self._min_sample = int(minval * max_adc)
self._max_sample = min(0xffff, int(math.ceil(maxval * max_adc)))
@ -357,9 +357,9 @@ class MCU:
self.serial.connect()
self._printer.reactor.update_timer(
self._timeout_timer, time.time() + self.COMM_TIMEOUT)
self._mcu_freq = float(self.serial.msgparser.config['CLOCK_FREQ'])
self._stats_sumsq_base = float(
self.serial.msgparser.config['STATS_SUMSQ_BASE'])
self._mcu_freq = self.serial.msgparser.get_constant_float('CLOCK_FREQ')
self._stats_sumsq_base = self.serial.msgparser.get_constant_float(
'STATS_SUMSQ_BASE')
self._emergency_stop_cmd = self.lookup_command("emergency_stop")
self._clear_shutdown_cmd = self.lookup_command("clear_shutdown")
self.register_msg(self.handle_shutdown, 'shutdown')
@ -424,7 +424,7 @@ class MCU:
self._num_oids,))
# Resolve pin names
mcu = self.serial.msgparser.config['MCU']
mcu = self.serial.msgparser.get_constant('MCU')
pin_map = self._config.get('pin_map', None)
if pin_map is None:
pnames = pins.mcu_to_pins(mcu)

View File

@ -308,3 +308,15 @@ class MessageParser:
self.static_strings = data.get('static_strings', [])
self.config.update(data.get('config', {}))
self.version = data.get('version', '')
def get_constant(self, name):
try:
return self.config[name]
except KeyError:
raise error("Firmware constant '%s' not found" % (name,))
def get_constant_float(self, name):
try:
return float(self.config[name])
except ValueError:
raise error("Firmware constant '%s' not a float" % (name,))
except KeyError:
raise error("Firmware constant '%s' not found" % (name,))