DFU mode UI

This commit is contained in:
rusefi 2019-08-14 23:58:47 -04:00
parent 9d178338b5
commit 15c9fac061
8 changed files with 111 additions and 38 deletions

View File

@ -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;

View File

@ -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;

View File

@ -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);

View File

@ -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());
}

View File

@ -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;
}
}

View File

@ -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");

View File

@ -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
* <p>
* (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)) {

View File

@ -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);
}
}