Startup Frame should scan for available hardware fix #4633
This commit is contained in:
parent
50344d32df
commit
771b907156
|
@ -2,11 +2,11 @@ package com.rusefi;
|
||||||
|
|
||||||
import com.rusefi.io.LinkManager;
|
import com.rusefi.io.LinkManager;
|
||||||
import com.rusefi.io.tcp.TcpConnector;
|
import com.rusefi.io.tcp.TcpConnector;
|
||||||
|
import com.rusefi.maintenance.DfuFlasher;
|
||||||
|
import com.rusefi.ui.StatusConsumer;
|
||||||
import org.jetbrains.annotations.NotNull;
|
import org.jetbrains.annotations.NotNull;
|
||||||
|
|
||||||
import java.util.ArrayList;
|
import java.util.*;
|
||||||
import java.util.Arrays;
|
|
||||||
import java.util.List;
|
|
||||||
import java.util.concurrent.CopyOnWriteArrayList;
|
import java.util.concurrent.CopyOnWriteArrayList;
|
||||||
|
|
||||||
import static com.rusefi.FileLog.isLinux;
|
import static com.rusefi.FileLog.isLinux;
|
||||||
|
@ -23,54 +23,66 @@ public enum SerialPortScanner {
|
||||||
private static final boolean SHOW_SOCKETCAN = isLinux();
|
private static final boolean SHOW_SOCKETCAN = isLinux();
|
||||||
|
|
||||||
static final String AUTO_SERIAL = "Auto Serial";
|
static final String AUTO_SERIAL = "Auto Serial";
|
||||||
@NotNull
|
|
||||||
private final List<String> knownPorts = new ArrayList<>();
|
|
||||||
|
|
||||||
public List<Listener> listeners = new CopyOnWriteArrayList<>();
|
private final Object lock = new Object();
|
||||||
|
@NotNull
|
||||||
|
private AvailableHardware knownHardware = new AvailableHardware(Collections.emptyList(), false, false);
|
||||||
|
|
||||||
|
private final List<Listener> listeners = new CopyOnWriteArrayList<>();
|
||||||
|
|
||||||
|
public void addListener(Listener listener) {
|
||||||
|
boolean shouldStart = listeners.isEmpty();
|
||||||
|
listeners.add(listener);
|
||||||
|
if (shouldStart)
|
||||||
|
startTimer();
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Find all available serial ports and checks if simulator local TCP port is available
|
* Find all available serial ports and checks if simulator local TCP port is available
|
||||||
*/
|
*/
|
||||||
private void findAllAvailablePorts(boolean includeSlowTcpLookup) {
|
private void findAllAvailablePorts(boolean includeSlowTcpLookup) {
|
||||||
List<String> ports = new ArrayList<>();
|
List<String> ports = new ArrayList<>();
|
||||||
|
boolean dfuConnected;
|
||||||
|
boolean stLinkConnected;
|
||||||
|
|
||||||
String[] serialPorts = LinkManager.getCommPorts();
|
String[] serialPorts = LinkManager.getCommPorts();
|
||||||
if (serialPorts.length > 0)
|
if (serialPorts.length > 0)
|
||||||
ports.add(AUTO_SERIAL);
|
ports.add(AUTO_SERIAL);
|
||||||
ports.addAll(Arrays.asList(serialPorts));
|
ports.addAll(Arrays.asList(serialPorts));
|
||||||
if (includeSlowTcpLookup)
|
|
||||||
|
if (includeSlowTcpLookup) {
|
||||||
ports.addAll(TcpConnector.getAvailablePorts());
|
ports.addAll(TcpConnector.getAvailablePorts());
|
||||||
|
dfuConnected = DfuFlasher.detectSTM32BootloaderDriverState(StatusConsumer.VOID);
|
||||||
|
stLinkConnected = DfuFlasher.detectStLink(StatusConsumer.VOID);
|
||||||
|
} else {
|
||||||
|
dfuConnected = false;
|
||||||
|
stLinkConnected = false;
|
||||||
|
}
|
||||||
if (SHOW_PCAN)
|
if (SHOW_PCAN)
|
||||||
ports.add(LinkManager.PCAN);
|
ports.add(LinkManager.PCAN);
|
||||||
if (SHOW_SOCKETCAN)
|
if (SHOW_SOCKETCAN)
|
||||||
ports.add(LinkManager.SOCKET_CAN);
|
ports.add(LinkManager.SOCKET_CAN);
|
||||||
|
|
||||||
boolean isListUpdated;
|
boolean isListUpdated;
|
||||||
synchronized (knownPorts) {
|
AvailableHardware currentHardware = new AvailableHardware(ports, dfuConnected, stLinkConnected);
|
||||||
isListUpdated = knownPorts.equals(ports);
|
synchronized (lock) {
|
||||||
knownPorts.clear();
|
isListUpdated = !knownHardware.equals(currentHardware);
|
||||||
knownPorts.addAll(ports);
|
knownHardware = currentHardware;
|
||||||
}
|
}
|
||||||
if (isListUpdated) {
|
if (isListUpdated) {
|
||||||
for (Listener listener : listeners)
|
for (Listener listener : listeners)
|
||||||
listener.onChange();
|
listener.onChange(currentHardware);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@NotNull
|
private void startTimer() {
|
||||||
public List<String> getKnownPorts() {
|
|
||||||
synchronized (knownPorts) {
|
|
||||||
return new ArrayList<>(knownPorts);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public void startTimer() {
|
|
||||||
Thread portsScanner = new Thread(() -> {
|
Thread portsScanner = new Thread(() -> {
|
||||||
boolean isFirstTime = true;
|
boolean isFirstTime = true;
|
||||||
while (isRunning) {
|
while (isRunning) {
|
||||||
findAllAvailablePorts(!isFirstTime);
|
findAllAvailablePorts(!isFirstTime);
|
||||||
isFirstTime = false;
|
isFirstTime = false;
|
||||||
try {
|
try {
|
||||||
Thread.sleep(1000);
|
Thread.sleep(300);
|
||||||
} catch (InterruptedException e) {
|
} catch (InterruptedException e) {
|
||||||
throw new IllegalStateException(e);
|
throw new IllegalStateException(e);
|
||||||
}
|
}
|
||||||
|
@ -86,6 +98,44 @@ public enum SerialPortScanner {
|
||||||
}
|
}
|
||||||
|
|
||||||
interface Listener {
|
interface Listener {
|
||||||
void onChange();
|
void onChange(AvailableHardware currentHardware);
|
||||||
|
}
|
||||||
|
|
||||||
|
public static class AvailableHardware {
|
||||||
|
|
||||||
|
private final List<String> ports;
|
||||||
|
private final boolean dfuFound;
|
||||||
|
private final boolean stLinkConnected;
|
||||||
|
|
||||||
|
public <T> AvailableHardware(List<String> ports, boolean dfuFound, boolean stLinkConnected) {
|
||||||
|
this.ports = ports;
|
||||||
|
this.dfuFound = dfuFound;
|
||||||
|
this.stLinkConnected = stLinkConnected;
|
||||||
|
}
|
||||||
|
|
||||||
|
@NotNull
|
||||||
|
public List<String> getKnownPorts() {
|
||||||
|
return new ArrayList<>(ports);
|
||||||
|
}
|
||||||
|
|
||||||
|
public boolean isDfuFound() {
|
||||||
|
return dfuFound;
|
||||||
|
}
|
||||||
|
|
||||||
|
public boolean isStLinkConnected() {
|
||||||
|
return stLinkConnected;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean equals(Object o) {
|
||||||
|
if (this == o) return true;
|
||||||
|
if (o == null || getClass() != o.getClass()) return false;
|
||||||
|
AvailableHardware that = (AvailableHardware) o;
|
||||||
|
return dfuFound == that.dfuFound && stLinkConnected == that.stLinkConnected && ports.equals(that.ports);
|
||||||
|
}
|
||||||
|
|
||||||
|
public boolean isEmpty() {
|
||||||
|
return !dfuFound && !stLinkConnected && ports.isEmpty();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -57,9 +57,6 @@ public class StartupFrame {
|
||||||
private final JPanel connectPanel = new JPanel(new FlowLayout());
|
private final JPanel connectPanel = new JPanel(new FlowLayout());
|
||||||
// todo: move this line to the connectPanel
|
// todo: move this line to the connectPanel
|
||||||
private final JComboBox<String> comboPorts = new JComboBox<>();
|
private final JComboBox<String> comboPorts = new JComboBox<>();
|
||||||
@NotNull
|
|
||||||
private List<String> currentlyDisplayedPorts = new ArrayList<>();
|
|
||||||
private boolean isFirstTimeApplyingPorts = true;
|
|
||||||
private final JPanel leftPanel = new JPanel(new VerticalFlowLayout());
|
private final JPanel leftPanel = new JPanel(new VerticalFlowLayout());
|
||||||
|
|
||||||
private final JPanel realHardwarePanel = new JPanel(new MigLayout());
|
private final JPanel realHardwarePanel = new JPanel(new MigLayout());
|
||||||
|
@ -93,7 +90,6 @@ public class StartupFrame {
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
AutoupdateUtil.setAppIcon(frame);
|
AutoupdateUtil.setAppIcon(frame);
|
||||||
SerialPortScanner.INSTANCE.startTimer();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@NotNull
|
@NotNull
|
||||||
|
@ -122,6 +118,7 @@ public class StartupFrame {
|
||||||
//connectButton.setBackground(new Color(RUSEFI_ORANGE)); // custom orange
|
//connectButton.setBackground(new Color(RUSEFI_ORANGE)); // custom orange
|
||||||
setToolTip(connectButton, "Connect to real hardware");
|
setToolTip(connectButton, "Connect to real hardware");
|
||||||
connectPanel.add(connectButton);
|
connectPanel.add(connectButton);
|
||||||
|
connectPanel.setVisible(false);
|
||||||
|
|
||||||
frame.getRootPane().setDefaultButton(connectButton);
|
frame.getRootPane().setDefaultButton(connectButton);
|
||||||
connectButton.addKeyListener(new KeyAdapter() {
|
connectButton.addKeyListener(new KeyAdapter() {
|
||||||
|
@ -149,10 +146,11 @@ public class StartupFrame {
|
||||||
realHardwarePanel.add(noPortsMessage, "right, wrap");
|
realHardwarePanel.add(noPortsMessage, "right, wrap");
|
||||||
installMessage(noPortsMessage, "Check you cables. Check your drivers. Do you want to start simulator maybe?");
|
installMessage(noPortsMessage, "Check you cables. Check your drivers. Do you want to start simulator maybe?");
|
||||||
|
|
||||||
|
ProgramSelector selector = new ProgramSelector(comboPorts);
|
||||||
|
|
||||||
if (FileLog.isWindows()) {
|
if (FileLog.isWindows()) {
|
||||||
realHardwarePanel.add(new HorizontalLine(), "right, wrap");
|
realHardwarePanel.add(new HorizontalLine(), "right, wrap");
|
||||||
|
|
||||||
ProgramSelector selector = new ProgramSelector(comboPorts);
|
|
||||||
realHardwarePanel.add(selector.getControl(), "right, wrap");
|
realHardwarePanel.add(selector.getControl(), "right, wrap");
|
||||||
|
|
||||||
// for F7 builds we just build one file at the moment
|
// for F7 builds we just build one file at the moment
|
||||||
|
@ -170,7 +168,11 @@ public class StartupFrame {
|
||||||
//realHardwarePanel.add(new EraseChip().getButton(), "right, wrap");
|
//realHardwarePanel.add(new EraseChip().getButton(), "right, wrap");
|
||||||
}
|
}
|
||||||
|
|
||||||
SerialPortScanner.INSTANCE.listeners.add(() -> SwingUtilities.invokeLater(this::applyKnownPorts));
|
SerialPortScanner.INSTANCE.addListener(currentHardware -> SwingUtilities.invokeLater(() -> {
|
||||||
|
selector.apply(currentHardware);
|
||||||
|
applyKnownPorts(currentHardware);
|
||||||
|
frame.pack();
|
||||||
|
}));
|
||||||
|
|
||||||
final JButton buttonLogViewer = new JButton();
|
final JButton buttonLogViewer = new JButton();
|
||||||
buttonLogViewer.setText("Start " + LinkManager.LOG_VIEWER);
|
buttonLogViewer.setText("Start " + LinkManager.LOG_VIEWER);
|
||||||
|
@ -226,19 +228,14 @@ public class StartupFrame {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private void applyKnownPorts() {
|
private void applyKnownPorts(SerialPortScanner.AvailableHardware currentHardware) {
|
||||||
List<String> ports = SerialPortScanner.INSTANCE.getKnownPorts();
|
List<String> ports = currentHardware.getKnownPorts();
|
||||||
if (!currentlyDisplayedPorts.equals(ports) || isFirstTimeApplyingPorts) {
|
|
||||||
log.info("Rendering available ports: " + ports);
|
log.info("Rendering available ports: " + ports);
|
||||||
isFirstTimeApplyingPorts = false;
|
|
||||||
connectPanel.setVisible(!ports.isEmpty());
|
connectPanel.setVisible(!ports.isEmpty());
|
||||||
noPortsMessage.setVisible(ports.isEmpty());
|
noPortsMessage.setVisible(ports.isEmpty());
|
||||||
|
|
||||||
applyPortSelectionToUIcontrol(ports);
|
applyPortSelectionToUIcontrol(ports);
|
||||||
currentlyDisplayedPorts = ports;
|
|
||||||
UiUtils.trueLayout(connectPanel);
|
UiUtils.trueLayout(connectPanel);
|
||||||
frame.pack();
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public static void setFrameIcon(Frame frame) {
|
public static void setFrameIcon(Frame frame) {
|
||||||
|
|
|
@ -1,10 +1,12 @@
|
||||||
package com.rusefi.maintenance;
|
package com.rusefi.maintenance;
|
||||||
|
|
||||||
import com.rusefi.Launcher;
|
import com.rusefi.Launcher;
|
||||||
|
import com.rusefi.SerialPortScanner;
|
||||||
import com.rusefi.autodetect.PortDetector;
|
import com.rusefi.autodetect.PortDetector;
|
||||||
import com.rusefi.autoupdate.AutoupdateUtil;
|
import com.rusefi.autoupdate.AutoupdateUtil;
|
||||||
import com.rusefi.ui.StatusWindow;
|
import com.rusefi.ui.StatusWindow;
|
||||||
import com.rusefi.ui.util.URLLabel;
|
import com.rusefi.ui.util.URLLabel;
|
||||||
|
import com.rusefi.ui.util.UiUtils;
|
||||||
import org.jetbrains.annotations.NotNull;
|
import org.jetbrains.annotations.NotNull;
|
||||||
|
|
||||||
import javax.swing.*;
|
import javax.swing.*;
|
||||||
|
@ -17,6 +19,7 @@ import java.util.Objects;
|
||||||
|
|
||||||
import static com.rusefi.StartupFrame.appendBundleName;
|
import static com.rusefi.StartupFrame.appendBundleName;
|
||||||
import static com.rusefi.ui.storage.PersistentConfiguration.getConfig;
|
import static com.rusefi.ui.storage.PersistentConfiguration.getConfig;
|
||||||
|
import static com.rusefi.ui.util.UiUtils.trueLayout;
|
||||||
|
|
||||||
public class ProgramSelector {
|
public class ProgramSelector {
|
||||||
|
|
||||||
|
@ -33,22 +36,16 @@ public class ProgramSelector {
|
||||||
public static final String BOOT_COMMANDER_EXE = "BootCommander.exe";
|
public static final String BOOT_COMMANDER_EXE = "BootCommander.exe";
|
||||||
public static final String OPENBLT_BINARY_LOCATION = Launcher.TOOLS_PATH + File.separator + "openblt";
|
public static final String OPENBLT_BINARY_LOCATION = Launcher.TOOLS_PATH + File.separator + "openblt";
|
||||||
|
|
||||||
|
|
||||||
|
private final JPanel content = new JPanel(new BorderLayout());
|
||||||
|
private final JLabel noHardware = new JLabel("Nothing detected");
|
||||||
private final JPanel controls = new JPanel(new FlowLayout());
|
private final JPanel controls = new JPanel(new FlowLayout());
|
||||||
private final JComboBox<String> mode = new JComboBox<>();
|
private final JComboBox<String> mode = new JComboBox<>();
|
||||||
|
|
||||||
public ProgramSelector(JComboBox<String> comboPorts) {
|
public ProgramSelector(JComboBox<String> comboPorts) {
|
||||||
/*
|
content.add(controls, BorderLayout.NORTH);
|
||||||
* todo: add FULL AUTO mode which would fire up DFU and ST-LINK in parallel hoping that one of those would work?
|
content.add(noHardware, BorderLayout.SOUTH);
|
||||||
*/
|
controls.setVisible(false);
|
||||||
if (IS_WIN) {
|
|
||||||
mode.addItem(AUTO_DFU);
|
|
||||||
mode.addItem(MANUAL_DFU);
|
|
||||||
mode.addItem(DFU_ERASE);
|
|
||||||
mode.addItem(ST_LINK);
|
|
||||||
mode.addItem(OPENBLT_CAN);
|
|
||||||
}
|
|
||||||
mode.addItem(DFU_SWITCH);
|
|
||||||
|
|
||||||
controls.add(mode);
|
controls.add(mode);
|
||||||
|
|
||||||
String persistedMode = getConfig().getRoot().getProperty(getClass().getSimpleName());
|
String persistedMode = getConfig().getRoot().getProperty(getClass().getSimpleName());
|
||||||
|
@ -117,6 +114,28 @@ public class ProgramSelector {
|
||||||
}
|
}
|
||||||
|
|
||||||
public JPanel getControl() {
|
public JPanel getControl() {
|
||||||
return controls;
|
return content;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void apply(SerialPortScanner.AvailableHardware currentHardware) {
|
||||||
|
noHardware.setVisible(currentHardware.isEmpty());
|
||||||
|
controls.setVisible(!currentHardware.isEmpty());
|
||||||
|
|
||||||
|
mode.removeAllItems();
|
||||||
|
if (IS_WIN) {
|
||||||
|
if (!currentHardware.getKnownPorts().isEmpty())
|
||||||
|
mode.addItem(AUTO_DFU);
|
||||||
|
if (currentHardware.isDfuFound()) {
|
||||||
|
mode.addItem(MANUAL_DFU);
|
||||||
|
mode.addItem(DFU_ERASE);
|
||||||
|
}
|
||||||
|
if (currentHardware.isStLinkConnected())
|
||||||
|
mode.addItem(ST_LINK);
|
||||||
|
// todo: detect PCAN mode.addItem(OPENBLT_CAN);
|
||||||
|
}
|
||||||
|
if (!currentHardware.getKnownPorts().isEmpty())
|
||||||
|
mode.addItem(DFU_SWITCH);
|
||||||
|
trueLayout(mode);
|
||||||
|
UiUtils.trueLayout(content);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue