From 2fed48763b8aeaa93225429964e79a491a66486f Mon Sep 17 00:00:00 2001 From: Ben Lye Date: Mon, 12 Apr 2021 15:39:05 +0100 Subject: [PATCH] Bootcommander tweaks * Require the printer to be connected * Use pySerial for M997 reset instead of echo --- octoprint_firmwareupdater/__init__.py | 8 --- octoprint_firmwareupdater/methods/bootcmdr.py | 50 +++++++++---------- .../static/js/firmwareupdater.js | 2 +- 3 files changed, 25 insertions(+), 35 deletions(-) diff --git a/octoprint_firmwareupdater/__init__.py b/octoprint_firmwareupdater/__init__.py index ab467ad..70bdc7b 100644 --- a/octoprint_firmwareupdater/__init__.py +++ b/octoprint_firmwareupdater/__init__.py @@ -730,14 +730,6 @@ def handle_connect_hook(self, *args, **kwargs): else: return False - ##~~ Connect hook - def handle_connect_hook(self, *args, **kwargs): - if self._settings.get_boolean(["prevent_connection_when_flashing"]) and self._flash_thread: - self._logger.info("Flash in progress, preventing connection to printer") - return True - else: - return False - ##~~ Update hook def update_hook(self): return dict( diff --git a/octoprint_firmwareupdater/methods/bootcmdr.py b/octoprint_firmwareupdater/methods/bootcmdr.py index 36fb4f6..8b611f5 100644 --- a/octoprint_firmwareupdater/methods/bootcmdr.py +++ b/octoprint_firmwareupdater/methods/bootcmdr.py @@ -1,6 +1,7 @@ import re import os import sarge +import serial import time CONNECTING = "Connecting to target bootloader" @@ -10,6 +11,8 @@ LOADING = "Loading firmware data from file" BACKDOOR = "Attempting backdoor entry" +current_baudrate = None + def _check_bootcmdr(self): bootcmdr_path = self.get_profile_setting("bootcmdr_path") pattern = re.compile("^(\/[^\0/]+)+$") @@ -29,11 +32,20 @@ def _check_bootcmdr(self): elif not os.access(bootcmdr_path, os.X_OK): self._logger.error(u"Path to BootCommander is not executable: {path}".format(path=bootcmdr_path)) return False + elif not self._printer.is_operational(): + self._logger.error("Printer is not connected") + self._send_status("flasherror", subtype="notconnected") + return False else: + global current_baudrate + _, current_port, current_baudrate, current_profile = self._printer.get_current_connection() return True + def _flash_bootcmdr(self, firmware=None, printer_port=None, **kwargs): assert(firmware is not None) + assert(printer_port is not None) + assert(current_baudrate is not None) bootcmdr_path = self.get_profile_setting("bootcmdr_path") bootcmdr_baudrate = self.get_profile_setting("bootcmdr_baudrate") @@ -52,15 +64,15 @@ def _flash_bootcmdr(self, firmware=None, printer_port=None, **kwargs): bootcmdr_command = bootcmdr_command.replace("{baudrate}", str(bootcmdr_baudrate)) bootcmdr_command = bootcmdr_command.replace("{firmware}", firmware) - self._logger.info(u"Running '{}' in {}".format(bootcmdr_command, working_dir)) - self._console_logger.info(bootcmdr_command) - if self.get_profile_setting_boolean("bootcmdr_preflashreset"): self._send_status("progress", subtype="boardreset") self._logger.info(u"Attempting to reset the board") - if not _reset_board(self, printer_port, bootcmdr_baudrate): + if not _reset_board(self, printer_port, current_baudrate): raise FlashException("Reset failed") + self._logger.info(u"Running '{}' in {}".format(bootcmdr_command, working_dir)) + self._console_logger.info(bootcmdr_command) + try: starttime = time.time() connecting = False @@ -119,31 +131,17 @@ def _flash_bootcmdr(self, firmware=None, printer_port=None, **kwargs): def _reset_board(self, printer_port=None, baudrate=None): assert(printer_port is not None) assert(baudrate is not None) - - self._logger.info(u"Resetting printer at '{port}'".format(port=printer_port)) - - # Configure the port - try: - os.system('stty -F ' + printer_port + ' speed ' + str(baudrate) + ' -echo > /dev/null') - except: - self._logger.exception(u"Error configuring serial port.") - self._send_status("flasherror", message="Board reset failed") - return False - # Smoothie reset command - try: - os.system('echo reset >> ' + printer_port) - except: - self._logger.exception(u"Error sending Smoothie 'reset' command.") - self._send_status("flasherror", message="Board reset failed") - return False + self._logger.info(u"Resetting printer at '{port}'".format(port=printer_port)) - # Marlin reset command try: - os.system('echo M997 >> ' + printer_port) - except: - self._logger.exception(u"Error sending Marlin 'M997' command.") - self._send_status("flasherror", message="Board reset failed") + ser = serial.Serial(printer_port, baudrate, timeout=1) + ser.write(b'reset\r\n') + ser.write(b'M997\r\n') + ser.flush() + ser.close() + except serial.SerialException: + self._logger.error(u"Board reset failed") return False return True diff --git a/octoprint_firmwareupdater/static/js/firmwareupdater.js b/octoprint_firmwareupdater/static/js/firmwareupdater.js index a302282..e790bba 100644 --- a/octoprint_firmwareupdater/static/js/firmwareupdater.js +++ b/octoprint_firmwareupdater/static/js/firmwareupdater.js @@ -557,7 +557,7 @@ $(function() { alert = gettext("The AVR MCU type is not selected."); } - if (self.getProfileSetting("flash_method") == "marlinbft" && !self.printerState.isReady()) { + if ((self.getProfileSetting("flash_method") == "marlinbft" || self.getProfileSetting("flash_method") == "bootcmdr") && !self.printerState.isReady()) { alert = gettext("The printer is not connected."); }