DFU mode UI
This commit is contained in:
parent
9d178338b5
commit
15c9fac061
|
@ -340,10 +340,7 @@ public class BinaryProtocol implements BinaryProtocolCommands {
|
||||||
* @return true in case of timeout, false if got proper confirmation
|
* @return true in case of timeout, false if got proper confirmation
|
||||||
*/
|
*/
|
||||||
private boolean sendTextCommand(String text) {
|
private boolean sendTextCommand(String text) {
|
||||||
byte[] asBytes = text.getBytes();
|
byte[] command = getTextCommandBytes(text);
|
||||||
byte[] command = new byte[asBytes.length + 1];
|
|
||||||
command[0] = 'E';
|
|
||||||
System.arraycopy(asBytes, 0, command, 1, asBytes.length);
|
|
||||||
|
|
||||||
long start = System.currentTimeMillis();
|
long start = System.currentTimeMillis();
|
||||||
while (!isClosed && (System.currentTimeMillis() - start < Timeouts.BINARY_IO_TIMEOUT)) {
|
while (!isClosed && (System.currentTimeMillis() - start < Timeouts.BINARY_IO_TIMEOUT)) {
|
||||||
|
@ -356,6 +353,14 @@ public class BinaryProtocol implements BinaryProtocolCommands {
|
||||||
return true;
|
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() {
|
private String requestPendingMessages() {
|
||||||
if (isClosed)
|
if (isClosed)
|
||||||
return null;
|
return null;
|
||||||
|
|
|
@ -113,6 +113,7 @@ public class PortHolder {
|
||||||
this.port = port;
|
this.port = port;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// todo: remove dead code - always true?
|
||||||
public boolean isConnected() {
|
public boolean isConnected() {
|
||||||
return isConnected;
|
return isConnected;
|
||||||
}
|
}
|
||||||
|
@ -123,10 +124,13 @@ public class PortHolder {
|
||||||
|
|
||||||
public EstablishConnection invoke() {
|
public EstablishConnection invoke() {
|
||||||
stream = SerialIoStreamJSerialComm.open(port, BAUD_RATE, FileLog.LOGGER);
|
stream = SerialIoStreamJSerialComm.open(port, BAUD_RATE, FileLog.LOGGER);
|
||||||
|
/*
|
||||||
|
todo: remove dead code
|
||||||
if (stream == null) {
|
if (stream == null) {
|
||||||
isConnected = false;
|
isConnected = false;
|
||||||
return this;
|
return this;
|
||||||
}
|
}
|
||||||
|
*/
|
||||||
|
|
||||||
isConnected = true;
|
isConnected = true;
|
||||||
return this;
|
return this;
|
||||||
|
|
|
@ -6,6 +6,7 @@ import com.fazecast.jSerialComm.SerialPortEvent;
|
||||||
import com.opensr5.Logger;
|
import com.opensr5.Logger;
|
||||||
import com.opensr5.io.DataListener;
|
import com.opensr5.io.DataListener;
|
||||||
import com.rusefi.io.IoStream;
|
import com.rusefi.io.IoStream;
|
||||||
|
import org.jetbrains.annotations.NotNull;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* https://github.com/Fazecast/jSerialComm looks to be alive as of 2019
|
* 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);
|
sp.writeBytes(bytes, bytes.length);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@NotNull
|
||||||
public static IoStream open(String port, int baudRate, Logger logger) {
|
public static IoStream open(String port, int baudRate, Logger logger) {
|
||||||
logger.info("[SerialIoStreamJSerialComm] " + port);
|
logger.info("[SerialIoStreamJSerialComm] " + port);
|
||||||
SerialPort sp = SerialPort.getCommPort(port);
|
SerialPort sp = SerialPort.getCommPort(port);
|
||||||
|
|
|
@ -4,10 +4,7 @@ import com.rusefi.autodetect.PortDetector;
|
||||||
import com.rusefi.io.LinkManager;
|
import com.rusefi.io.LinkManager;
|
||||||
import com.rusefi.io.serial.PortHolder;
|
import com.rusefi.io.serial.PortHolder;
|
||||||
import com.rusefi.io.tcp.TcpConnector;
|
import com.rusefi.io.tcp.TcpConnector;
|
||||||
import com.rusefi.maintenance.DriverInstall;
|
import com.rusefi.maintenance.*;
|
||||||
import com.rusefi.maintenance.EraseChip;
|
|
||||||
import com.rusefi.maintenance.ExecHelper;
|
|
||||||
import com.rusefi.maintenance.FirmwareFlasher;
|
|
||||||
import com.rusefi.ui.util.HorizontalLine;
|
import com.rusefi.ui.util.HorizontalLine;
|
||||||
import com.rusefi.ui.util.URLLabel;
|
import com.rusefi.ui.util.URLLabel;
|
||||||
import com.rusefi.ui.util.UiUtils;
|
import com.rusefi.ui.util.UiUtils;
|
||||||
|
@ -152,11 +149,12 @@ public class StartupFrame {
|
||||||
|
|
||||||
if (FileLog.isWindows()) {
|
if (FileLog.isWindows()) {
|
||||||
realHardwarePanel.add(new HorizontalLine());
|
realHardwarePanel.add(new HorizontalLine());
|
||||||
|
realHardwarePanel.add(new DfuFlasher(comboPorts).getButton());
|
||||||
// for F7 builds we just build one file at the moment
|
// 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()) {
|
if (new File(FirmwareFlasher.IMAGE_NO_ASSERTS_FILE).exists()) {
|
||||||
// 407 build
|
// 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());
|
realHardwarePanel.add(new EraseChip().getButton());
|
||||||
}
|
}
|
||||||
|
|
|
@ -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<String> 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;
|
||||||
|
}
|
||||||
|
}
|
|
@ -1,5 +1,6 @@
|
||||||
package com.rusefi.maintenance;
|
package com.rusefi.maintenance;
|
||||||
|
|
||||||
|
import com.rusefi.ui.StatusWindow;
|
||||||
import org.jetbrains.annotations.NotNull;
|
import org.jetbrains.annotations.NotNull;
|
||||||
|
|
||||||
import javax.swing.*;
|
import javax.swing.*;
|
||||||
|
@ -10,11 +11,12 @@ import static com.rusefi.maintenance.FirmwareFlasher.TITLE;
|
||||||
/**
|
/**
|
||||||
* (c) Andrey Belomutskiy 2013-2018
|
* (c) Andrey Belomutskiy 2013-2018
|
||||||
*/
|
*/
|
||||||
public class EraseChip extends ProcessStatusWindow {
|
public class EraseChip {
|
||||||
private static final String FLASH_SIZE = "0x0100000";
|
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 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() {
|
public EraseChip() {
|
||||||
button.addActionListener(new AbstractAction() {
|
button.addActionListener(new AbstractAction() {
|
||||||
|
@ -27,7 +29,7 @@ public class EraseChip extends ProcessStatusWindow {
|
||||||
wnd.showFrame(TITLE);
|
wnd.showFrame(TITLE);
|
||||||
StatusAnimation sa = new StatusAnimation(wnd);
|
StatusAnimation sa = new StatusAnimation(wnd);
|
||||||
ExecHelper.submitAction(() -> {
|
ExecHelper.submitAction(() -> {
|
||||||
executeCommand(getEraseCommand());
|
FirmwareFlasher.executeOpenOCDCommand(getEraseCommand(), wnd);
|
||||||
sa.stop();
|
sa.stop();
|
||||||
wnd.setStatus(FirmwareFlasher.DONE);
|
wnd.setStatus(FirmwareFlasher.DONE);
|
||||||
}, EraseChip.this.getClass() + " extProcessThread");
|
}, EraseChip.this.getClass() + " extProcessThread");
|
||||||
|
|
|
@ -1,5 +1,6 @@
|
||||||
package com.rusefi.maintenance;
|
package com.rusefi.maintenance;
|
||||||
|
|
||||||
|
import com.rusefi.ui.StatusWindow;
|
||||||
import org.jetbrains.annotations.NotNull;
|
import org.jetbrains.annotations.NotNull;
|
||||||
|
|
||||||
import javax.swing.*;
|
import javax.swing.*;
|
||||||
|
@ -11,28 +12,29 @@ import static com.rusefi.Launcher.INPUT_FILES_PATH;
|
||||||
import static com.rusefi.ui.storage.PersistentConfiguration.getConfig;
|
import static com.rusefi.ui.storage.PersistentConfiguration.getConfig;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
* @see DfuFlasher
|
||||||
|
* <p>
|
||||||
* (c) Andrey Belomutskiy 2013-2018
|
* (c) Andrey Belomutskiy 2013-2018
|
||||||
* 2/4/15
|
* 2/4/15
|
||||||
*/
|
*/
|
||||||
public class FirmwareFlasher extends ProcessStatusWindow {
|
public class FirmwareFlasher {
|
||||||
// Even on Windows openOCD insists on "/" for path separator
|
// 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_FILE = INPUT_FILES_PATH + "/" + "rusefi.bin";
|
||||||
public static final String IMAGE_NO_ASSERTS_FILE = INPUT_FILES_PATH + "/" + "rusefi_no_asserts.bin";
|
public static final String IMAGE_NO_ASSERTS_FILE = INPUT_FILES_PATH + "/" + "rusefi_no_asserts.bin";
|
||||||
/**
|
/**
|
||||||
* SWD ST-LINK/V2 mode
|
* SWD ST-LINK/V2 mode
|
||||||
*/
|
*/
|
||||||
static final String OPENOCD_EXE = "openocd/openocd.exe";
|
private 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";
|
|
||||||
static final String BINARY_LOCATION = ".";
|
static final String BINARY_LOCATION = ".";
|
||||||
private static final String SUCCESS_MESSAGE_TAG = "shutdown command invoked";
|
private static final String SUCCESS_MESSAGE_TAG = "shutdown command invoked";
|
||||||
private static final String FAILED_MESSAGE_TAG = "failed";
|
private static final String FAILED_MESSAGE_TAG = "failed";
|
||||||
private static final String NO_DRIVER_MESSAGE_TAG = "failed with LIBUSB_ERROR_NOT_SUPPORTED";
|
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!";
|
public static final String DONE = "DONE!";
|
||||||
|
|
||||||
private final JButton button;
|
private final JButton button;
|
||||||
private String fileName;
|
private String fileName;
|
||||||
|
private StatusWindow wnd = new StatusWindow();
|
||||||
|
|
||||||
public FirmwareFlasher(String fileName, String buttonTest, String tooltip) {
|
public FirmwareFlasher(String fileName, String buttonTest, String tooltip) {
|
||||||
this.fileName = fileName;
|
this.fileName = fileName;
|
||||||
|
@ -59,6 +61,12 @@ public class FirmwareFlasher extends ProcessStatusWindow {
|
||||||
return OPENOCD_EXE + " -f openocd/" + cfg;
|
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() {
|
private void doFlashFirmware() {
|
||||||
if (!new File(fileName).exists()) {
|
if (!new File(fileName).exists()) {
|
||||||
wnd.appendMsg(fileName + " not found, cannot proceed !!!");
|
wnd.appendMsg(fileName + " not found, cannot proceed !!!");
|
||||||
|
@ -66,9 +74,9 @@ public class FirmwareFlasher extends ProcessStatusWindow {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
StatusAnimation sa = new StatusAnimation(wnd);
|
StatusAnimation sa = new StatusAnimation(wnd);
|
||||||
StringBuffer error = executeCommand(getOpenocdCommand() + " -c \"program " +
|
StringBuffer error = executeOpenOCDCommand(getOpenocdCommand() + " -c \"program " +
|
||||||
fileName +
|
fileName +
|
||||||
" verify reset exit 0x08000000\"");
|
" verify reset exit 0x08000000\"", wnd);
|
||||||
if (error.toString().contains(NO_DRIVER_MESSAGE_TAG)) {
|
if (error.toString().contains(NO_DRIVER_MESSAGE_TAG)) {
|
||||||
wnd.appendMsg(" !!! ERROR: looks like stm32 driver is not installed? The link is above !!!");
|
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)) {
|
} else if (error.toString().contains(SUCCESS_MESSAGE_TAG) && !error.toString().toLowerCase().contains(FAILED_MESSAGE_TAG)) {
|
||||||
|
|
|
@ -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);
|
|
||||||
}
|
|
||||||
}
|
|
Loading…
Reference in New Issue