536 lines
16 KiB
Java
536 lines
16 KiB
Java
package fabrik.simulator.pic16f84;
|
|
|
|
import com.gluonhq.charm.glisten.control.ToggleButtonGroup;
|
|
|
|
import javafx.application.Platform;
|
|
import javafx.collections.FXCollections;
|
|
import javafx.collections.ObservableList;
|
|
import javafx.event.ActionEvent;
|
|
import javafx.fxml.FXML;
|
|
|
|
import javafx.scene.Scene;
|
|
import javafx.scene.control.*;
|
|
import javafx.scene.layout.VBox;
|
|
import javafx.scene.shape.Circle;
|
|
import javafx.stage.FileChooser;
|
|
|
|
import java.io.File;
|
|
import java.io.IOException;
|
|
|
|
import java.io.BufferedReader;
|
|
|
|
import java.io.FileReader;
|
|
|
|
import javafx.scene.control.Label;
|
|
import javafx.scene.control.TableView;
|
|
|
|
import javafx.stage.Stage;
|
|
import javafx.util.Callback;
|
|
|
|
|
|
import java.util.Arrays;
|
|
import java.util.HashSet;
|
|
import java.util.Set;
|
|
|
|
public class Controller_Frontend {
|
|
|
|
private int [] prog;
|
|
private int [][] read;
|
|
private int [] ind;
|
|
|
|
private double executionTimeMultiplier = 1;
|
|
|
|
|
|
|
|
|
|
|
|
@FXML
|
|
private ComboBox<String> executionTimeComboBox;
|
|
|
|
|
|
@FXML
|
|
private Button stepintoButton;
|
|
|
|
@FXML
|
|
private TableView<Table.DataEntry> tableView;
|
|
|
|
@FXML
|
|
private ListView<String> lstContentListView;
|
|
|
|
@FXML
|
|
private Label pclLabel;
|
|
|
|
@FXML
|
|
private Label statusLabel;
|
|
|
|
@FXML
|
|
private Label fsrLabel;
|
|
|
|
@FXML
|
|
private Label pclathLabel;
|
|
|
|
@FXML
|
|
private Label intconLabel;
|
|
|
|
@FXML
|
|
private Button stepButton;
|
|
|
|
@FXML
|
|
private Button autoRunGUI;
|
|
|
|
@FXML
|
|
private Button stopButton;
|
|
|
|
@FXML
|
|
private Label totalExecutionTimeLabel;
|
|
|
|
@FXML
|
|
private CheckBox wdtCheck;
|
|
|
|
|
|
|
|
private static volatile boolean isAutoRunActive = false;
|
|
private static volatile boolean isSleeping = false;
|
|
|
|
public static boolean isSleeping (){
|
|
return isSleeping;
|
|
}
|
|
|
|
public static void stopRunFromBackend(String message){
|
|
isAutoRunActive = false;
|
|
if (isSleeping)
|
|
wakeUpFromSleep();
|
|
else
|
|
DataRegister.resetPC();
|
|
// Stage stoppedStage = new Stage();
|
|
// stoppedStage.setTitle("Programm unterbrochen!");
|
|
// VBox vbox = new VBox();
|
|
// vbox.setAlignment(javafx.geometry.Pos.CENTER);
|
|
// Label grundlabel = new Label("Grund: " + message);
|
|
// grundlabel.setStyle("-fx-font-size: 16px; -fx-font-weight: bold;");
|
|
// Label ueberlabel = new Label("Programm unterbrochen!");
|
|
// vbox.getChildren().add(ueberlabel);
|
|
// vbox.getChildren().add(grundlabel);
|
|
// VBox.setMargin(grundlabel, new javafx.geometry.Insets(10, 10, 10, 10));
|
|
// Scene scene = new Scene(vbox, 300, 90);
|
|
// stoppedStage.setAlwaysOnTop(true);
|
|
// stoppedStage.setScene(scene);
|
|
// stoppedStage.show();
|
|
}
|
|
|
|
public static void sleep() {
|
|
isSleeping = true;
|
|
}
|
|
|
|
public static void wakeUpFromSleep() {
|
|
isSleeping = false;
|
|
}
|
|
|
|
@FXML
|
|
private void stopAutoRun(ActionEvent event) {
|
|
isAutoRunActive = false;
|
|
}
|
|
|
|
|
|
@FXML
|
|
private void autoRunGUI(ActionEvent event) {
|
|
if (!isAutoRunActive) {
|
|
isAutoRunActive = true;
|
|
}
|
|
Thread autoRunThread = new Thread(() -> {
|
|
try {
|
|
while (DataRegister.getPC() < prog.length && isAutoRunActive){
|
|
|
|
Platform.runLater(() -> {
|
|
try {
|
|
stepintoButton(null);
|
|
} catch (IOException e) {
|
|
e.printStackTrace();
|
|
}
|
|
});
|
|
Thread.sleep(80); //Verzögerungszeit in Millisekunden
|
|
}
|
|
} catch (InterruptedException e) {
|
|
e.printStackTrace();
|
|
}
|
|
});
|
|
autoRunThread.setDaemon(true);
|
|
autoRunThread.start();
|
|
}
|
|
|
|
|
|
private void updateExecutionTimeMultiplier() {
|
|
String selectedOption = executionTimeComboBox.getValue();
|
|
switch (selectedOption) {
|
|
case "8 MHZ":
|
|
executionTimeMultiplier = 0.5;
|
|
break;
|
|
|
|
case "4 MHZ":
|
|
executionTimeMultiplier = 1;
|
|
break;
|
|
case "1 MHZ":
|
|
executionTimeMultiplier = 4;
|
|
break;
|
|
case "500 HZ":
|
|
executionTimeMultiplier = 8;
|
|
break;
|
|
|
|
case "100 HZ":
|
|
executionTimeMultiplier = 40;
|
|
break;
|
|
|
|
case "32 HZ":
|
|
executionTimeMultiplier = 125;
|
|
break;
|
|
}
|
|
}
|
|
|
|
@FXML
|
|
private void stepintoButton(ActionEvent event) throws IOException {
|
|
if (lstContentListView.getItems().isEmpty()) {
|
|
// Datei ist nicht geladen oder leer
|
|
return;
|
|
}
|
|
|
|
int currentIndex;
|
|
// Aktuelle Zeile abrufen
|
|
if (!isSleeping)
|
|
currentIndex = ind[DataRegister.getPC()];
|
|
else
|
|
currentIndex = ind[DataRegister.getPC()]-1;
|
|
|
|
// Überprüfen, ob ein Breakpoint gesetzt ist testte
|
|
if (breakpoints.contains(currentIndex)) {
|
|
stopAutoRun(null);
|
|
System.out.println("Breakpoint erreicht bei Zeile: " + currentIndex);
|
|
return;
|
|
}
|
|
|
|
|
|
// Scrollen zur ausgewählten Zeile
|
|
lstContentListView.scrollTo(currentIndex -2);
|
|
|
|
// Zeile auswählen
|
|
lstContentListView.getSelectionModel().clearSelection();
|
|
lstContentListView.getSelectionModel().select(currentIndex);
|
|
|
|
String selectedRowStyle;
|
|
if (!isSleeping)
|
|
selectedRowStyle = "-fx-background-color: red; -fx-text-fill: white;";
|
|
else
|
|
selectedRowStyle = "-fx-background-color: teal; -fx-text-fill: white;";
|
|
|
|
markSelectedRow(currentIndex, selectedRowStyle);
|
|
|
|
|
|
|
|
if (!isSleeping) {
|
|
Commands.decode(prog[DataRegister.getPC()]);
|
|
DataRegister.increasePC();
|
|
}
|
|
else {
|
|
Commands.decode(0);
|
|
|
|
}
|
|
WatchdogTimer.testAndTrigger();
|
|
Table.refresh();
|
|
Stage stage = (Stage) stepintoButton.getScene().getWindow();
|
|
CreateWindow.refreshTable(stage);
|
|
IOPorts.refreshUI(getTRISbuttons(), getPORTbuttons());
|
|
|
|
long totalExecutionTime = Commands.getTotalExecutionTime();
|
|
double adjustedTotalExecutionTime = totalExecutionTime * executionTimeMultiplier;
|
|
totalExecutionTimeLabel.setText("Total Execution Time: " + adjustedTotalExecutionTime + "µs");
|
|
}
|
|
|
|
private void markSelectedRow(int currentIndex, String selectedRowStyle) {
|
|
lstContentListView.setCellFactory(column -> new ListCell<String>() {
|
|
@Override
|
|
protected void updateItem(String item, boolean empty) {
|
|
super.updateItem(item, empty);
|
|
setText(item);
|
|
if (getIndex() == currentIndex) {
|
|
setStyle(selectedRowStyle);
|
|
} else {
|
|
setStyle("");
|
|
}
|
|
}
|
|
});
|
|
}
|
|
|
|
private Set<Integer> breakpoints = new HashSet<>();
|
|
|
|
|
|
|
|
@FXML
|
|
protected void selectFileLST(ActionEvent event) throws IOException {
|
|
File selectedFile = chooseLSTFile();
|
|
stopAutoRun(null);
|
|
if(selectedFile != null){
|
|
DataRegister.initDataRegister();
|
|
DataRegister.resetPC();
|
|
initialize();
|
|
toggleLEDs(null);
|
|
IOPorts.reset();
|
|
for (ToggleButtonGroup toggleButtonGroup : allPORTbuttons) {
|
|
try {
|
|
toggleButtonGroup.getToggles().get(0).setSelected(true);
|
|
toggleButtonGroup.getToggles().get(1).setSelected(false);
|
|
IOPorts.setPORTfromUI(toggleButtonGroup);
|
|
} catch (NullPointerException ignored) {}
|
|
}
|
|
IOPorts.refreshUI(getTRISbuttons(), getPORTbuttons());
|
|
Commands.resetTotalExecutionTime();
|
|
WatchdogTimer.reset();
|
|
wdtCheck.setSelected(false);
|
|
Table.refresh();
|
|
read = ParseFile.parseDatei(selectedFile.getAbsolutePath());
|
|
prog = read [0];
|
|
ind = read[1];
|
|
System.out.println(Arrays.toString(Arrays.stream(prog).toArray()));
|
|
displayLSTFileContent(selectedFile);
|
|
markSelectedRow(0, "-fx-background-color: red; -fx-text-fill: white;");
|
|
initializeBreakpoints();
|
|
}
|
|
|
|
|
|
}
|
|
|
|
private void initializeBreakpoints() {
|
|
lstContentListView.setCellFactory(createBreakpointCell());
|
|
}
|
|
|
|
private boolean checkBreakpoint(int pc) {
|
|
// Hier wird überprüft, ob ein Breakpoint am angegebenen Programmzähler gesetzt ist
|
|
return breakpoints.contains(pc);
|
|
}
|
|
|
|
|
|
private Callback<ListView<String>, ListCell<String>> createBreakpointCell() {
|
|
return listView -> new ListCell<String>() {
|
|
private final CheckBox breakpointCheckBox = new CheckBox();
|
|
|
|
{
|
|
breakpointCheckBox.setOnAction(event -> {
|
|
int index = getIndex();
|
|
if (breakpointCheckBox.isSelected()) {
|
|
breakpoints.add(index);
|
|
} else {
|
|
breakpoints.remove(index);
|
|
}
|
|
});
|
|
}
|
|
|
|
@Override
|
|
protected void updateItem(String item, boolean empty) {
|
|
super.updateItem(item, empty);
|
|
if (empty || item == null) {
|
|
setGraphic(null);
|
|
} else {
|
|
setText(item);
|
|
setGraphic(breakpointCheckBox);
|
|
breakpointCheckBox.setSelected(breakpoints.contains(getIndex()));
|
|
}
|
|
}
|
|
};
|
|
}
|
|
|
|
@FXML
|
|
protected void loadLSTFileContent(String fileContent) {
|
|
ObservableList<String> items = FXCollections.observableArrayList(fileContent.split("\n"));
|
|
lstContentListView.setItems(items);
|
|
}
|
|
|
|
|
|
private File chooseLSTFile() {
|
|
FileChooser fileChooser = new FileChooser();
|
|
fileChooser.setTitle("Open LST File");
|
|
fileChooser.getExtensionFilters().addAll(
|
|
new FileChooser.ExtensionFilter("LST Files", "*.lst", "*.LST"),
|
|
new FileChooser.ExtensionFilter("All Files", "*.*"));
|
|
return fileChooser.showOpenDialog(null);
|
|
}
|
|
|
|
@FXML
|
|
private void displayLSTFileContent(File selectedFile) {
|
|
try (BufferedReader reader = new BufferedReader(new FileReader(selectedFile))) {
|
|
ObservableList<String> contentList = FXCollections.observableArrayList();
|
|
String line;
|
|
while ((line = reader.readLine()) != null) {
|
|
contentList.add(line);
|
|
}
|
|
lstContentListView.setItems(contentList);
|
|
} catch (IOException e) {
|
|
e.printStackTrace();
|
|
}
|
|
}
|
|
|
|
@FXML
|
|
public void toggleWatchdog(ActionEvent actionEvent) {
|
|
if (wdtCheck.isSelected())
|
|
WatchdogTimer.enable();
|
|
else
|
|
WatchdogTimer.disable();
|
|
}
|
|
|
|
@FXML
|
|
private ToggleButtonGroup bgTRISA0;
|
|
@FXML
|
|
private ToggleButtonGroup bgTRISA1;
|
|
@FXML
|
|
private ToggleButtonGroup bgTRISA2;
|
|
@FXML
|
|
private ToggleButtonGroup bgTRISA3;
|
|
@FXML
|
|
private ToggleButtonGroup bgTRISA4;
|
|
@FXML
|
|
private ToggleButtonGroup bgTRISB0;
|
|
@FXML
|
|
private ToggleButtonGroup bgTRISB1;
|
|
@FXML
|
|
private ToggleButtonGroup bgTRISB2;
|
|
@FXML
|
|
private ToggleButtonGroup bgTRISB3;
|
|
@FXML
|
|
private ToggleButtonGroup bgTRISB4;
|
|
@FXML
|
|
private ToggleButtonGroup bgTRISB5;
|
|
@FXML
|
|
private ToggleButtonGroup bgTRISB6;
|
|
@FXML
|
|
private ToggleButtonGroup bgTRISB7;
|
|
@FXML
|
|
private ToggleButtonGroup bgPORTA0;
|
|
@FXML
|
|
private ToggleButtonGroup bgPORTA1;
|
|
@FXML
|
|
private ToggleButtonGroup bgPORTA2;
|
|
@FXML
|
|
private ToggleButtonGroup bgPORTA3;
|
|
@FXML
|
|
private ToggleButtonGroup bgPORTA4;
|
|
@FXML
|
|
private ToggleButtonGroup bgPORTB0;
|
|
@FXML
|
|
private ToggleButtonGroup bgPORTB1;
|
|
@FXML
|
|
private ToggleButtonGroup bgPORTB2;
|
|
@FXML
|
|
private ToggleButtonGroup bgPORTB3;
|
|
@FXML
|
|
private ToggleButtonGroup bgPORTB4;
|
|
@FXML
|
|
private ToggleButtonGroup bgPORTB5;
|
|
@FXML
|
|
private ToggleButtonGroup bgPORTB6;
|
|
@FXML
|
|
private ToggleButtonGroup bgPORTB7;
|
|
|
|
private static ToggleButtonGroup[] allTRISbuttons;
|
|
private static ToggleButtonGroup[] allPORTbuttons;
|
|
private static Circle[] allLEDsA;
|
|
private static Circle[] allLEDsB;
|
|
private static ToggleButtonGroup dummy = new ToggleButtonGroup(new ToggleButton(), new ToggleButton());
|
|
|
|
public void initialize() {
|
|
ToggleButtonGroup [] allTRISButtons = {bgTRISA0, bgTRISA1, bgTRISA2, bgTRISA3, bgTRISA4, dummy, dummy, dummy, bgTRISB0, bgTRISB1, bgTRISB2, bgTRISB3, bgTRISB4, bgTRISB5, bgTRISB6, bgTRISB7};
|
|
ToggleButtonGroup [] allPORTButtons = {bgPORTA0, bgPORTA1, bgPORTA2, bgPORTA3, bgPORTA4, dummy, dummy, dummy, bgPORTB0, bgPORTB1, bgPORTB2, bgPORTB3, bgPORTB4, bgPORTB5, bgPORTB6, bgPORTB7};
|
|
Circle[] allLEDsA = {ledA0, ledA1, ledA2, ledA3, ledA4};
|
|
Circle[] allLEDsB = {ledB0, ledB1, ledB2, ledB3, ledB4, ledB5, ledB6, ledB7};
|
|
for (int i = 0; i<allPORTButtons.length; i++) {
|
|
allTRISButtons[i].getToggles().get(0).setSelected(true);
|
|
allPORTButtons[i].getToggles().get(0).setSelected(true);
|
|
allTRISButtons[i].getToggles().get(1).setSelected(false);
|
|
allPORTButtons[i].getToggles().get(1).setSelected(false);
|
|
ToggleButtonGroupExt.get().addAlwaysOneSelectedSupport(allTRISButtons[i]);
|
|
ToggleButtonGroupExt.get().addAlwaysOneSelectedSupport(allPORTButtons[i]);
|
|
}
|
|
|
|
ledCheckA.setSelected(false);
|
|
ledCheckB.setSelected(false);
|
|
setTRISbuttons(allTRISButtons);
|
|
setPORTbuttons(allPORTButtons);
|
|
IOPorts.setLEDs(allLEDsA, allLEDsB);
|
|
|
|
lstContentListView.getSelectionModel().setSelectionMode(SelectionMode.MULTIPLE);
|
|
|
|
autoRunGUI.setOnAction(this::autoRunGUI);
|
|
stopButton.setOnAction(this::stopAutoRun);
|
|
|
|
|
|
executionTimeComboBox.setItems(FXCollections.observableArrayList("8 MHZ", "4 MHZ", "1 MHZ", "500 HZ", "100 HZ", "32 HZ"));
|
|
executionTimeComboBox.setValue("4 MHZ");
|
|
executionTimeComboBox.setOnAction(event -> updateExecutionTimeMultiplier());
|
|
lstContentListView.setCellFactory(createBreakpointCell());
|
|
|
|
}
|
|
|
|
|
|
|
|
private static void setTRISbuttons(ToggleButtonGroup[] allButtons) {
|
|
allTRISbuttons = allButtons;
|
|
}
|
|
|
|
public static ToggleButtonGroup [] getTRISbuttons() {
|
|
return allTRISbuttons;
|
|
}
|
|
|
|
private static void setPORTbuttons(ToggleButtonGroup[] allButtons) {
|
|
allPORTbuttons = allButtons;
|
|
}
|
|
|
|
public static ToggleButtonGroup [] getPORTbuttons() {
|
|
return allPORTbuttons;
|
|
}
|
|
|
|
public static Circle[] getLEDsA() {
|
|
return allLEDsA;
|
|
}
|
|
|
|
public static Circle[] getLEDsB() {
|
|
return allLEDsB;
|
|
}
|
|
|
|
|
|
@FXML
|
|
private CheckBox ledCheckA;
|
|
@FXML
|
|
private CheckBox ledCheckB;
|
|
@FXML
|
|
private Circle ledA0;
|
|
@FXML
|
|
private Circle ledA1;
|
|
@FXML
|
|
private Circle ledA2;
|
|
@FXML
|
|
private Circle ledA3;
|
|
@FXML
|
|
private Circle ledA4;
|
|
@FXML
|
|
private Circle ledB0;
|
|
@FXML
|
|
private Circle ledB1;
|
|
@FXML
|
|
private Circle ledB2;
|
|
@FXML
|
|
private Circle ledB3;
|
|
@FXML
|
|
private Circle ledB4;
|
|
@FXML
|
|
private Circle ledB5;
|
|
@FXML
|
|
private Circle ledB6;
|
|
@FXML
|
|
private Circle ledB7;
|
|
|
|
@FXML
|
|
public void toggleLEDs (ActionEvent actionEvent) {
|
|
IOPorts.setLEDs(new boolean[]{ledCheckA.isSelected(), ledCheckB.isSelected()});
|
|
}
|
|
}
|
|
|
|
|
|
|
|
|