diff --git a/java_console/io/src/com/rusefi/binaryprotocol/BinaryProtocol.java b/java_console/io/src/com/rusefi/binaryprotocol/BinaryProtocol.java index c237a99c3a..5940013f9e 100644 --- a/java_console/io/src/com/rusefi/binaryprotocol/BinaryProtocol.java +++ b/java_console/io/src/com/rusefi/binaryprotocol/BinaryProtocol.java @@ -340,10 +340,7 @@ public class BinaryProtocol implements BinaryProtocolCommands { * @return true in case of timeout, false if got proper confirmation */ private boolean sendTextCommand(String text) { - byte[] asBytes = text.getBytes(); - byte[] command = new byte[asBytes.length + 1]; - command[0] = 'E'; - System.arraycopy(asBytes, 0, command, 1, asBytes.length); + byte[] command = getTextCommandBytes(text); long start = System.currentTimeMillis(); while (!isClosed && (System.currentTimeMillis() - start < Timeouts.BINARY_IO_TIMEOUT)) { @@ -356,6 +353,14 @@ public class BinaryProtocol implements BinaryProtocolCommands { return true; } + public static byte[] getTextCommandBytes(String text) { + byte[] asBytes = text.getBytes(); + byte[] command = new byte[asBytes.length + 1]; + command[0] = 'E'; + System.arraycopy(asBytes, 0, command, 1, asBytes.length); + return command; + } + private String requestPendingMessages() { if (isClosed) return null; diff --git a/java_console/io/src/com/rusefi/io/serial/PortHolder.java b/java_console/io/src/com/rusefi/io/serial/PortHolder.java index 32360f0e0c..6e3819aec3 100644 --- a/java_console/io/src/com/rusefi/io/serial/PortHolder.java +++ b/java_console/io/src/com/rusefi/io/serial/PortHolder.java @@ -113,6 +113,7 @@ public class PortHolder { this.port = port; } + // todo: remove dead code - always true? public boolean isConnected() { return isConnected; } @@ -123,10 +124,13 @@ public class PortHolder { public EstablishConnection invoke() { stream = SerialIoStreamJSerialComm.open(port, BAUD_RATE, FileLog.LOGGER); +/* +todo: remove dead code if (stream == null) { isConnected = false; return this; } + */ isConnected = true; return this; diff --git a/java_console/io/src/com/rusefi/io/serial/SerialIoStreamJSerialComm.java b/java_console/io/src/com/rusefi/io/serial/SerialIoStreamJSerialComm.java index ea3a98ed97..f322d9e9a1 100644 --- a/java_console/io/src/com/rusefi/io/serial/SerialIoStreamJSerialComm.java +++ b/java_console/io/src/com/rusefi/io/serial/SerialIoStreamJSerialComm.java @@ -6,6 +6,7 @@ import com.fazecast.jSerialComm.SerialPortEvent; import com.opensr5.Logger; import com.opensr5.io.DataListener; import com.rusefi.io.IoStream; +import org.jetbrains.annotations.NotNull; /** * https://github.com/Fazecast/jSerialComm looks to be alive as of 2019 @@ -66,6 +67,7 @@ public class SerialIoStreamJSerialComm implements IoStream { sp.writeBytes(bytes, bytes.length); } + @NotNull public static IoStream open(String port, int baudRate, Logger logger) { logger.info("[SerialIoStreamJSerialComm] " + port); SerialPort sp = SerialPort.getCommPort(port); diff --git a/java_console/ui/src/com/rusefi/StartupFrame.java b/java_console/ui/src/com/rusefi/StartupFrame.java index 45435d2921..836f0277a7 100644 --- a/java_console/ui/src/com/rusefi/StartupFrame.java +++ b/java_console/ui/src/com/rusefi/StartupFrame.java @@ -4,10 +4,7 @@ import com.rusefi.autodetect.PortDetector; import com.rusefi.io.LinkManager; import com.rusefi.io.serial.PortHolder; import com.rusefi.io.tcp.TcpConnector; -import com.rusefi.maintenance.DriverInstall; -import com.rusefi.maintenance.EraseChip; -import com.rusefi.maintenance.ExecHelper; -import com.rusefi.maintenance.FirmwareFlasher; +import com.rusefi.maintenance.*; import com.rusefi.ui.util.HorizontalLine; import com.rusefi.ui.util.URLLabel; import com.rusefi.ui.util.UiUtils; @@ -152,11 +149,12 @@ public class StartupFrame { if (FileLog.isWindows()) { realHardwarePanel.add(new HorizontalLine()); + realHardwarePanel.add(new DfuFlasher(comboPorts).getButton()); // for F7 builds we just build one file at the moment - realHardwarePanel.add(new FirmwareFlasher(FirmwareFlasher.IMAGE_FILE, "Program Firmware", "Default firmware version for most users").getButton()); + realHardwarePanel.add(new FirmwareFlasher(FirmwareFlasher.IMAGE_FILE, "ST-LINK Program Firmware", "Default firmware version for most users").getButton()); if (new File(FirmwareFlasher.IMAGE_NO_ASSERTS_FILE).exists()) { // 407 build - realHardwarePanel.add(new FirmwareFlasher(FirmwareFlasher.IMAGE_NO_ASSERTS_FILE, "Program Firmware/NoAsserts", "Please only use this version if you know that you need this version").getButton()); + realHardwarePanel.add(new FirmwareFlasher(FirmwareFlasher.IMAGE_NO_ASSERTS_FILE, "ST-LINK Program Firmware/NoAsserts", "Please only use this version if you know that you need this version").getButton()); } realHardwarePanel.add(new EraseChip().getButton()); } diff --git a/java_console/ui/src/com/rusefi/maintenance/DfuFlasher.java b/java_console/ui/src/com/rusefi/maintenance/DfuFlasher.java new file mode 100644 index 0000000000..1e084c2eca --- /dev/null +++ b/java_console/ui/src/com/rusefi/maintenance/DfuFlasher.java @@ -0,0 +1,72 @@ +package com.rusefi.maintenance; + +import com.rusefi.FileLog; +import com.rusefi.Launcher; +import com.rusefi.Timeouts; +import com.rusefi.autodetect.PortDetector; +import com.rusefi.binaryprotocol.BinaryProtocol; +import com.rusefi.config.generated.Fields; +import com.rusefi.io.IoStream; +import com.rusefi.io.serial.PortHolder; +import com.rusefi.io.serial.SerialIoStreamJSerialComm; +import com.rusefi.ui.StatusWindow; + +import javax.swing.*; +import java.awt.*; +import java.awt.event.ActionEvent; +import java.awt.event.ActionListener; +import java.io.File; +import java.io.IOException; + +/** + * @see FirmwareFlasher + */ +public class DfuFlasher { + public static final String DFU_BINARY = "DfuSe/DfuSeCommand.exe"; + // TODO: integration with DFU command line tool + static final String DFU_COMMAND = DFU_BINARY + " -c -d --v --fn " + Launcher.INPUT_FILES_PATH + File.separator + + "rusefi.dfu"; + + private final JButton button = new JButton("Program via DFU"); + + public DfuFlasher(JComboBox comboPorts) { + button.addActionListener(new ActionListener() { + @Override + public void actionPerformed(ActionEvent event) { + String port = comboPorts.getSelectedItem().toString(); + port = PortDetector.autoDetectSerialIfNeeded(port); + if (port == null) + return; + IoStream stream = SerialIoStreamJSerialComm.open(port, PortHolder.BAUD_RATE, FileLog.LOGGER); + byte[] command = BinaryProtocol.getTextCommandBytes(Fields.CMD_REBOOT_DFU); + try { + stream.sendPacket(command, FileLog.LOGGER); + stream.close(); + } catch (IOException e) { + e.printStackTrace(); + } + + StatusWindow wnd = new StatusWindow(); + wnd.showFrame("DFU status"); + ExecHelper.submitAction(() -> executeDFU(wnd), getClass() + " thread"); + } + }); + } + + private void executeDFU(StatusWindow wnd) { + wnd.appendMsg("Giving time for USB enumeration..."); + try { + Thread.sleep(3 * Timeouts.SECOND); + } catch (InterruptedException e) { + throw new IllegalStateException(e); + } + ExecHelper.executeCommand(FirmwareFlasher.BINARY_LOCATION, + FirmwareFlasher.BINARY_LOCATION + File.separator + DFU_COMMAND, + DFU_BINARY, wnd); + wnd.appendMsg("Please power cycle device to exit DFU mode"); + } + + public Component getButton() { + return button; + } +} diff --git a/java_console/ui/src/com/rusefi/maintenance/EraseChip.java b/java_console/ui/src/com/rusefi/maintenance/EraseChip.java index 376a24001b..9176ff3b70 100644 --- a/java_console/ui/src/com/rusefi/maintenance/EraseChip.java +++ b/java_console/ui/src/com/rusefi/maintenance/EraseChip.java @@ -1,5 +1,6 @@ package com.rusefi.maintenance; +import com.rusefi.ui.StatusWindow; import org.jetbrains.annotations.NotNull; import javax.swing.*; @@ -10,11 +11,12 @@ import static com.rusefi.maintenance.FirmwareFlasher.TITLE; /** * (c) Andrey Belomutskiy 2013-2018 */ -public class EraseChip extends ProcessStatusWindow { +public class EraseChip { private static final String FLASH_SIZE = "0x0100000"; private static final String ERASE_COMMAND_SUFFIX = " -c init -c targets -c \"halt\" -c \"flash erase_address 0x08000000 " + FLASH_SIZE + "\" -c shutdown"; - private final JButton button = new JButton("Erase Chip"); + private final JButton button = new JButton("ST-LINK Erase Chip"); + private StatusWindow wnd = new StatusWindow(); public EraseChip() { button.addActionListener(new AbstractAction() { @@ -27,7 +29,7 @@ public class EraseChip extends ProcessStatusWindow { wnd.showFrame(TITLE); StatusAnimation sa = new StatusAnimation(wnd); ExecHelper.submitAction(() -> { - executeCommand(getEraseCommand()); + FirmwareFlasher.executeOpenOCDCommand(getEraseCommand(), wnd); sa.stop(); wnd.setStatus(FirmwareFlasher.DONE); }, EraseChip.this.getClass() + " extProcessThread"); diff --git a/java_console/ui/src/com/rusefi/maintenance/FirmwareFlasher.java b/java_console/ui/src/com/rusefi/maintenance/FirmwareFlasher.java index 8c786b9f6f..014b642406 100644 --- a/java_console/ui/src/com/rusefi/maintenance/FirmwareFlasher.java +++ b/java_console/ui/src/com/rusefi/maintenance/FirmwareFlasher.java @@ -1,5 +1,6 @@ package com.rusefi.maintenance; +import com.rusefi.ui.StatusWindow; import org.jetbrains.annotations.NotNull; import javax.swing.*; @@ -11,28 +12,29 @@ import static com.rusefi.Launcher.INPUT_FILES_PATH; import static com.rusefi.ui.storage.PersistentConfiguration.getConfig; /** + * @see DfuFlasher + *

* (c) Andrey Belomutskiy 2013-2018 * 2/4/15 */ -public class FirmwareFlasher extends ProcessStatusWindow { +public class FirmwareFlasher { // Even on Windows openOCD insists on "/" for path separator public static final String IMAGE_FILE = INPUT_FILES_PATH + "/" + "rusefi.bin"; public static final String IMAGE_NO_ASSERTS_FILE = INPUT_FILES_PATH + "/" + "rusefi_no_asserts.bin"; /** * SWD ST-LINK/V2 mode */ - static final String OPENOCD_EXE = "openocd/openocd.exe"; - // TODO: integration with DFU command line tool - static final String DFU_EXE = "DfuSeCommand.exe -c -d --v --fn rusefi.dfu"; + private static final String OPENOCD_EXE = "openocd/openocd.exe"; static final String BINARY_LOCATION = "."; private static final String SUCCESS_MESSAGE_TAG = "shutdown command invoked"; private static final String FAILED_MESSAGE_TAG = "failed"; private static final String NO_DRIVER_MESSAGE_TAG = "failed with LIBUSB_ERROR_NOT_SUPPORTED"; - public static final String TITLE = "rusEfi Firmware Flasher"; + public static final String TITLE = "rusEfi ST-LINK Firmware Flasher"; public static final String DONE = "DONE!"; private final JButton button; private String fileName; + private StatusWindow wnd = new StatusWindow(); public FirmwareFlasher(String fileName, String buttonTest, String tooltip) { this.fileName = fileName; @@ -59,6 +61,12 @@ public class FirmwareFlasher extends ProcessStatusWindow { return OPENOCD_EXE + " -f openocd/" + cfg; } + protected static StringBuffer executeOpenOCDCommand(String command, StatusWindow wnd) { + return ExecHelper.executeCommand(BINARY_LOCATION, + BINARY_LOCATION + File.separator + command, + OPENOCD_EXE, wnd); + } + private void doFlashFirmware() { if (!new File(fileName).exists()) { wnd.appendMsg(fileName + " not found, cannot proceed !!!"); @@ -66,9 +74,9 @@ public class FirmwareFlasher extends ProcessStatusWindow { return; } StatusAnimation sa = new StatusAnimation(wnd); - StringBuffer error = executeCommand(getOpenocdCommand() + " -c \"program " + + StringBuffer error = executeOpenOCDCommand(getOpenocdCommand() + " -c \"program " + fileName + - " verify reset exit 0x08000000\""); + " verify reset exit 0x08000000\"", wnd); if (error.toString().contains(NO_DRIVER_MESSAGE_TAG)) { wnd.appendMsg(" !!! ERROR: looks like stm32 driver is not installed? The link is above !!!"); } else if (error.toString().contains(SUCCESS_MESSAGE_TAG) && !error.toString().toLowerCase().contains(FAILED_MESSAGE_TAG)) { diff --git a/java_console/ui/src/com/rusefi/maintenance/ProcessStatusWindow.java b/java_console/ui/src/com/rusefi/maintenance/ProcessStatusWindow.java deleted file mode 100644 index e9bf990b70..0000000000 --- a/java_console/ui/src/com/rusefi/maintenance/ProcessStatusWindow.java +++ /dev/null @@ -1,18 +0,0 @@ -package com.rusefi.maintenance; - -import com.rusefi.ui.StatusWindow; - -import java.io.File; - -/** - * (c) Andrey Belomutskiy 2013-2018 - */ -public class ProcessStatusWindow { - protected final StatusWindow wnd = new StatusWindow(); - - protected StringBuffer executeCommand(String command) { - return ExecHelper.executeCommand(FirmwareFlasher.BINARY_LOCATION, - FirmwareFlasher.BINARY_LOCATION + File.separator + command, - FirmwareFlasher.OPENOCD_EXE, wnd); - } -} \ No newline at end of file