mirror of https://github.com/FOME-Tech/fome-fw.git
rusEFI console to has "Erase via DFU" button #2250
This commit is contained in:
parent
16e025a7fc
commit
44754607ef
|
@ -22,6 +22,7 @@ public class PortDetector {
|
||||||
private final static Logging log = Logging.getLogging(PortDetector.class);
|
private final static Logging log = Logging.getLogging(PortDetector.class);
|
||||||
|
|
||||||
private static final NamedThreadFactory AUTO_DETECT_PORT = new NamedThreadFactory("AutoDetectPort");
|
private static final NamedThreadFactory AUTO_DETECT_PORT = new NamedThreadFactory("AutoDetectPort");
|
||||||
|
public static final String AUTO = "auto";
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Connect to all serial ports and find out which one respond first
|
* Connect to all serial ports and find out which one respond first
|
||||||
|
@ -111,6 +112,6 @@ public class PortDetector {
|
||||||
}
|
}
|
||||||
|
|
||||||
public static boolean isAutoPort(String port) {
|
public static boolean isAutoPort(String port) {
|
||||||
return port.toLowerCase().startsWith("auto");
|
return port.toLowerCase().startsWith(AUTO);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -6,6 +6,7 @@ import com.rusefi.SignatureHelper;
|
||||||
import com.rusefi.autoupdate.Autoupdate;
|
import com.rusefi.autoupdate.Autoupdate;
|
||||||
import com.rusefi.binaryprotocol.BinaryProtocol;
|
import com.rusefi.binaryprotocol.BinaryProtocol;
|
||||||
import com.rusefi.config.generated.Fields;
|
import com.rusefi.config.generated.Fields;
|
||||||
|
import com.rusefi.ui.StatusConsumer;
|
||||||
|
|
||||||
import javax.swing.*;
|
import javax.swing.*;
|
||||||
import java.io.IOException;
|
import java.io.IOException;
|
||||||
|
@ -16,7 +17,7 @@ import static com.rusefi.binaryprotocol.BinaryProtocol.sleep;
|
||||||
public class DfuHelper {
|
public class DfuHelper {
|
||||||
private static final String PREFIX = "rusefi_bundle";
|
private static final String PREFIX = "rusefi_bundle";
|
||||||
|
|
||||||
public static void sendDfuRebootCommand(IoStream stream, StringBuilder messages) {
|
public static void sendDfuRebootCommand(IoStream stream, StatusConsumer messages) {
|
||||||
byte[] command = BinaryProtocol.getTextCommandBytes(Fields.CMD_REBOOT_DFU);
|
byte[] command = BinaryProtocol.getTextCommandBytes(Fields.CMD_REBOOT_DFU);
|
||||||
try {
|
try {
|
||||||
stream.sendPacket(command);
|
stream.sendPacket(command);
|
||||||
|
@ -27,7 +28,7 @@ public class DfuHelper {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public static boolean sendDfuRebootCommand(JComponent parent, String signature, IoStream stream, StringBuilder messages) {
|
public static boolean sendDfuRebootCommand(JComponent parent, String signature, IoStream stream, StatusConsumer messages) {
|
||||||
RusEfiSignature s = SignatureHelper.parse(signature);
|
RusEfiSignature s = SignatureHelper.parse(signature);
|
||||||
String bundleName = Autoupdate.readBundleFullName();
|
String bundleName = Autoupdate.readBundleFullName();
|
||||||
if (bundleName != null && s != null) {
|
if (bundleName != null && s != null) {
|
||||||
|
|
|
@ -2,4 +2,6 @@ package com.rusefi.ui;
|
||||||
|
|
||||||
public interface StatusConsumer {
|
public interface StatusConsumer {
|
||||||
void appendMsg(String s);
|
void appendMsg(String s);
|
||||||
|
|
||||||
|
void append(String s);
|
||||||
}
|
}
|
|
@ -11,6 +11,7 @@ import com.rusefi.io.IoStream;
|
||||||
import com.rusefi.io.serial.SerialIoStreamJSerialComm;
|
import com.rusefi.io.serial.SerialIoStreamJSerialComm;
|
||||||
import com.rusefi.ui.StatusWindow;
|
import com.rusefi.ui.StatusWindow;
|
||||||
import org.jetbrains.annotations.NotNull;
|
import org.jetbrains.annotations.NotNull;
|
||||||
|
import org.jetbrains.annotations.Nullable;
|
||||||
|
|
||||||
import javax.swing.*;
|
import javax.swing.*;
|
||||||
import java.io.BufferedReader;
|
import java.io.BufferedReader;
|
||||||
|
@ -40,46 +41,11 @@ public class DfuFlasher {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
String port = selectedItem.toString();
|
String port = selectedItem.toString();
|
||||||
StringBuilder messages = new StringBuilder();
|
|
||||||
|
|
||||||
AtomicBoolean isSignatureValidated = new AtomicBoolean(true);
|
StatusWindow wnd = createStatusWindow();
|
||||||
if (!PortDetector.isAutoPort(port)) {
|
|
||||||
messages.append("Using selected " + port + "\n");
|
AtomicBoolean isSignatureValidated = rebootToDfu(parent, port, wnd);
|
||||||
IoStream stream = SerialIoStreamJSerialComm.openPort(port);
|
if (isSignatureValidated == null) return;
|
||||||
AtomicReference<String> signature = new AtomicReference<>();
|
|
||||||
new SerialAutoChecker(port, new CountDownLatch(1)).checkResponse(stream, new Function<SerialAutoChecker.CallbackContext, Void>() {
|
|
||||||
@Override
|
|
||||||
public Void apply(SerialAutoChecker.CallbackContext callbackContext) {
|
|
||||||
signature.set(callbackContext.getSignature());
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
});
|
|
||||||
if (signature.get() == null) {
|
|
||||||
JOptionPane.showMessageDialog(ConsoleUI.getFrame(), "rusEFI has not responded on selected " + port + "\n" +
|
|
||||||
"Maybe try automatic serial port detection?");
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
boolean isSignatureValidatedLocal = DfuHelper.sendDfuRebootCommand(parent, signature.get(), stream, messages);
|
|
||||||
isSignatureValidated.set(isSignatureValidatedLocal);
|
|
||||||
} else {
|
|
||||||
messages.append("Auto-detecting port...\n");
|
|
||||||
// instead of opening the just-detected port we execute the command using the same stream we used to discover port
|
|
||||||
// it's more reliable this way
|
|
||||||
port = PortDetector.autoDetectSerial(callbackContext -> {
|
|
||||||
boolean isSignatureValidatedLocal = DfuHelper.sendDfuRebootCommand(parent, callbackContext.getSignature(), callbackContext.getStream(), messages);
|
|
||||||
isSignatureValidated.set(isSignatureValidatedLocal);
|
|
||||||
return null;
|
|
||||||
}).getSerialPort();
|
|
||||||
if (port == null) {
|
|
||||||
JOptionPane.showMessageDialog(ConsoleUI.getFrame(), "rusEFI serial port not detected");
|
|
||||||
return;
|
|
||||||
} else {
|
|
||||||
messages.append("Detected rusEFI on " + port + "\n");
|
|
||||||
}
|
|
||||||
}
|
|
||||||
StatusWindow wnd = new StatusWindow();
|
|
||||||
wnd.showFrame(appendBundleName("DFU status " + Launcher.CONSOLE_VERSION));
|
|
||||||
wnd.appendMsg(messages.toString());
|
|
||||||
if (isSignatureValidated.get()) {
|
if (isSignatureValidated.get()) {
|
||||||
if (!ProgramSelector.IS_WIN) {
|
if (!ProgramSelector.IS_WIN) {
|
||||||
wnd.appendMsg("Switched to DFU mode!");
|
wnd.appendMsg("Switched to DFU mode!");
|
||||||
|
@ -95,9 +61,55 @@ public class DfuFlasher {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public static void runDfuProgramming() {
|
@Nullable
|
||||||
|
public static AtomicBoolean rebootToDfu(JComponent parent, String port, StatusWindow wnd) {
|
||||||
|
AtomicBoolean isSignatureValidated = new AtomicBoolean(true);
|
||||||
|
if (!PortDetector.isAutoPort(port)) {
|
||||||
|
wnd.append("Using selected " + port + "\n");
|
||||||
|
IoStream stream = SerialIoStreamJSerialComm.openPort(port);
|
||||||
|
AtomicReference<String> signature = new AtomicReference<>();
|
||||||
|
new SerialAutoChecker(port, new CountDownLatch(1)).checkResponse(stream, new Function<SerialAutoChecker.CallbackContext, Void>() {
|
||||||
|
@Override
|
||||||
|
public Void apply(SerialAutoChecker.CallbackContext callbackContext) {
|
||||||
|
signature.set(callbackContext.getSignature());
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
});
|
||||||
|
if (signature.get() == null) {
|
||||||
|
JOptionPane.showMessageDialog(ConsoleUI.getFrame(), "rusEFI has not responded on selected " + port + "\n" +
|
||||||
|
"Maybe try automatic serial port detection?");
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
boolean isSignatureValidatedLocal = DfuHelper.sendDfuRebootCommand(parent, signature.get(), stream, wnd);
|
||||||
|
isSignatureValidated.set(isSignatureValidatedLocal);
|
||||||
|
} else {
|
||||||
|
wnd.append("Auto-detecting port...\n");
|
||||||
|
// instead of opening the just-detected port we execute the command using the same stream we used to discover port
|
||||||
|
// it's more reliable this way
|
||||||
|
port = PortDetector.autoDetectSerial(callbackContext -> {
|
||||||
|
boolean isSignatureValidatedLocal = DfuHelper.sendDfuRebootCommand(parent, callbackContext.getSignature(), callbackContext.getStream(), wnd);
|
||||||
|
isSignatureValidated.set(isSignatureValidatedLocal);
|
||||||
|
return null;
|
||||||
|
}).getSerialPort();
|
||||||
|
if (port == null) {
|
||||||
|
JOptionPane.showMessageDialog(ConsoleUI.getFrame(), "rusEFI serial port not detected");
|
||||||
|
return null;
|
||||||
|
} else {
|
||||||
|
wnd.append("Detected rusEFI on " + port + "\n");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return isSignatureValidated;
|
||||||
|
}
|
||||||
|
|
||||||
|
@NotNull
|
||||||
|
protected static StatusWindow createStatusWindow() {
|
||||||
StatusWindow wnd = new StatusWindow();
|
StatusWindow wnd = new StatusWindow();
|
||||||
wnd.showFrame(appendBundleName("DFU status " + Launcher.CONSOLE_VERSION));
|
wnd.showFrame(appendBundleName("DFU status " + Launcher.CONSOLE_VERSION));
|
||||||
|
return wnd;
|
||||||
|
}
|
||||||
|
|
||||||
|
public static void runDfuProgramming() {
|
||||||
|
StatusWindow wnd = createStatusWindow();
|
||||||
ExecHelper.submitAction(() -> executeDFU(wnd), DfuFlasher.class + " thread");
|
ExecHelper.submitAction(() -> executeDFU(wnd), DfuFlasher.class + " thread");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -1,6 +1,8 @@
|
||||||
package com.rusefi.maintenance;
|
package com.rusefi.maintenance;
|
||||||
|
|
||||||
|
import com.rusefi.autodetect.PortDetector;
|
||||||
import com.rusefi.autoupdate.AutoupdateUtil;
|
import com.rusefi.autoupdate.AutoupdateUtil;
|
||||||
|
import com.rusefi.ui.StatusWindow;
|
||||||
import com.rusefi.ui.util.URLLabel;
|
import com.rusefi.ui.util.URLLabel;
|
||||||
import org.jetbrains.annotations.NotNull;
|
import org.jetbrains.annotations.NotNull;
|
||||||
|
|
||||||
|
@ -16,6 +18,8 @@ public class ProgramSelector {
|
||||||
|
|
||||||
private static final String AUTO_DFU = "Auto DFU";
|
private static final String AUTO_DFU = "Auto DFU";
|
||||||
private static final String MANUAL_DFU = "Manual DFU";
|
private static final String MANUAL_DFU = "Manual DFU";
|
||||||
|
private static final String DFU_SWITCH = "Switch to DFU";
|
||||||
|
private static final String DFU_ERASE = "Full Erase";
|
||||||
private static final String ST_LINK = "ST-LINK";
|
private static final String ST_LINK = "ST-LINK";
|
||||||
public static final boolean IS_WIN = System.getProperty("os.name").toLowerCase().contains("win");
|
public static final boolean IS_WIN = System.getProperty("os.name").toLowerCase().contains("win");
|
||||||
|
|
||||||
|
@ -31,13 +35,15 @@ public class ProgramSelector {
|
||||||
mode.addItem(AUTO_DFU);
|
mode.addItem(AUTO_DFU);
|
||||||
if (IS_WIN) {
|
if (IS_WIN) {
|
||||||
mode.addItem(MANUAL_DFU);
|
mode.addItem(MANUAL_DFU);
|
||||||
|
mode.addItem(DFU_ERASE);
|
||||||
mode.addItem(ST_LINK);
|
mode.addItem(ST_LINK);
|
||||||
}
|
}
|
||||||
|
mode.addItem(DFU_SWITCH);
|
||||||
|
|
||||||
controls.add(mode);
|
controls.add(mode);
|
||||||
|
|
||||||
String persistedMode = getConfig().getRoot().getProperty(getClass().getSimpleName());
|
String persistedMode = getConfig().getRoot().getProperty(getClass().getSimpleName());
|
||||||
if (Arrays.asList(AUTO_DFU, MANUAL_DFU, ST_LINK).contains(persistedMode))
|
if (Arrays.asList(AUTO_DFU, MANUAL_DFU, ST_LINK, DFU_ERASE, DFU_SWITCH).contains(persistedMode))
|
||||||
mode.setSelectedItem(persistedMode);
|
mode.setSelectedItem(persistedMode);
|
||||||
|
|
||||||
JButton updateFirmware = new JButton("Update Firmware",
|
JButton updateFirmware = new JButton("Update Firmware",
|
||||||
|
@ -51,16 +57,21 @@ public class ProgramSelector {
|
||||||
|
|
||||||
getConfig().getRoot().setProperty(getClass().getSimpleName(), selectedMode);
|
getConfig().getRoot().setProperty(getClass().getSimpleName(), selectedMode);
|
||||||
|
|
||||||
boolean isAutoDfu = selectedMode.equals(AUTO_DFU);
|
|
||||||
boolean isManualDfu = selectedMode.equals(MANUAL_DFU);
|
|
||||||
// todo: add ST-LINK no-assert mode
|
|
||||||
|
|
||||||
if (isAutoDfu) {
|
if (selectedMode.equals(AUTO_DFU)) {
|
||||||
DfuFlasher.doAutoDfu(comboPorts.getSelectedItem(), comboPorts);
|
DfuFlasher.doAutoDfu(comboPorts.getSelectedItem(), comboPorts);
|
||||||
} else if (isManualDfu) {
|
} else if (selectedMode.equals(MANUAL_DFU)) {
|
||||||
DfuFlasher.runDfuProgramming();
|
DfuFlasher.runDfuProgramming();
|
||||||
} else {
|
} else if (selectedMode.equals(ST_LINK)) {
|
||||||
|
// todo: add ST-LINK no-assert mode? or not?
|
||||||
FirmwareFlasher.doUpdateFirmware(FirmwareFlasher.IMAGE_FILE, updateFirmware);
|
FirmwareFlasher.doUpdateFirmware(FirmwareFlasher.IMAGE_FILE, updateFirmware);
|
||||||
|
} else if (selectedMode.equals(DFU_SWITCH)) {
|
||||||
|
StatusWindow wnd = DfuFlasher.createStatusWindow();
|
||||||
|
Object selected = comboPorts.getSelectedItem();
|
||||||
|
String port = selected == null ? PortDetector.AUTO : selected.toString();
|
||||||
|
DfuFlasher.rebootToDfu(comboPorts, port, wnd);
|
||||||
|
} else {
|
||||||
|
throw new IllegalArgumentException("How did you " + selectedMode);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
|
@ -72,6 +72,11 @@ public class StatusWindow implements StatusConsumer {
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void append(String s) {
|
||||||
|
appendMsg(s);
|
||||||
|
}
|
||||||
|
|
||||||
public void setStatus(String status) {
|
public void setStatus(String status) {
|
||||||
bottomStatusLabel.setText(status);
|
bottomStatusLabel.setText(status);
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue