From e6bf2658ac86dcacc9540f9efd348a6ffc7647ff Mon Sep 17 00:00:00 2001 From: hneemann Date: Sat, 5 Dec 2020 17:28:23 +0100 Subject: [PATCH] adds a attribute to select the trigger mode --- .../de/neemann/digital/core/element/Keys.java | 8 ++++ .../gui/components/data/GraphDialog.java | 37 ++++++++------- .../gui/components/data/ScopeTrigger.java | 46 ++++++++++++++++--- src/main/resources/lang/lang_de.xml | 18 +++++--- src/main/resources/lang/lang_en.xml | 6 +++ 5 files changed, 86 insertions(+), 29 deletions(-) diff --git a/src/main/java/de/neemann/digital/core/element/Keys.java b/src/main/java/de/neemann/digital/core/element/Keys.java index 231681773..9b84c99d5 100644 --- a/src/main/java/de/neemann/digital/core/element/Keys.java +++ b/src/main/java/de/neemann/digital/core/element/Keys.java @@ -20,6 +20,7 @@ import de.neemann.digital.draw.library.ElementLibrary; import de.neemann.digital.draw.model.InverterConfig; import de.neemann.digital.draw.shapes.CustomCircuitShapeType; import de.neemann.digital.draw.shapes.custom.CustomShapeDescription; +import de.neemann.digital.gui.components.data.ScopeTrigger; import de.neemann.digital.testing.TestCaseDescription; import de.neemann.gui.Screen; import de.neemann.gui.language.Language; @@ -876,4 +877,11 @@ public final class Keys { public static final Key TESTDATA = new Key<>("Testdata", TestCaseDescription::new); + /** + * The scope trigger mode + */ + public static final Key.KeyEnum TRIGGER = + new Key.KeyEnum<>("trigger", ScopeTrigger.Trigger.both, ScopeTrigger.Trigger.values()); + + } diff --git a/src/main/java/de/neemann/digital/gui/components/data/GraphDialog.java b/src/main/java/de/neemann/digital/gui/components/data/GraphDialog.java index d8ad5e36c..580603b60 100644 --- a/src/main/java/de/neemann/digital/gui/components/data/GraphDialog.java +++ b/src/main/java/de/neemann/digital/gui/components/data/GraphDialog.java @@ -72,7 +72,7 @@ public class GraphDialog extends JDialog implements Observer { ValueTableObserver valueTableObserver = new ValueTableObserver(microStep, signals, MAX_SAMPLE_SIZE); - GraphDialog graphDialog = new GraphDialog(owner, title, valueTableObserver.getLogData(), model) + GraphDialog graphDialog = new GraphDialog(owner, title, valueTableObserver.getLogData(), model, true) .setColumnInfo(createColumnsInfo(signals)); graphDialog.addWindowListener(new WindowAdapter() { @@ -90,7 +90,7 @@ public class GraphDialog extends JDialog implements Observer { return graphDialog; } - private static ValueTable.ColumnInfo[] createColumnsInfo(ArrayList signals) { + static ValueTable.ColumnInfo[] createColumnsInfo(ArrayList signals) { ValueTable.ColumnInfo[] info = new ValueTable.ColumnInfo[signals.size()]; for (int i = 0; i < signals.size(); i++) { Signal s = signals.get(i); @@ -107,7 +107,7 @@ public class GraphDialog extends JDialog implements Observer { * @param logData the data to visualize */ public GraphDialog(Window owner, String title, ValueTable logData) { - this(owner, title, logData, SyncAccess.NOSYNC); + this(owner, title, logData, SyncAccess.NOSYNC, true); } /** @@ -117,8 +117,9 @@ public class GraphDialog extends JDialog implements Observer { * @param title the frame title * @param logData the data to visualize * @param modelSync used to access the running model + * @param showHelp shows the help menu item */ - private GraphDialog(Window owner, String title, ValueTable logData, SyncAccess modelSync) { + GraphDialog(Window owner, String title, ValueTable logData, SyncAccess modelSync, boolean showHelp) { super(owner, title, ModalityType.MODELESS); setDefaultCloseOperation(DISPOSE_ON_CLOSE); @@ -190,25 +191,27 @@ public class GraphDialog extends JDialog implements Observer { view.addSeparator(); view.add(showTable.createJMenuItem()); - JMenu help = new JMenu(Lang.get("menu_help")); - bar.add(help); - help.add(new ToolTipAction(Lang.get("btn_help")) { - @Override - public void actionPerformed(ActionEvent e) { - new ShowStringDialog( - GraphDialog.this, - Lang.get("msg_graphHelpTitle"), - Lang.get("msg_graphHelp"), true) - .setVisible(true); - } - }.createJMenuItem()); + if (showHelp) { + JMenu help = new JMenu(Lang.get("menu_help")); + bar.add(help); + help.add(new ToolTipAction(Lang.get("btn_help")) { + @Override + public void actionPerformed(ActionEvent e) { + new ShowStringDialog( + GraphDialog.this, + Lang.get("msg_graphHelpTitle"), + Lang.get("msg_graphHelp"), true) + .setVisible(true); + } + }.createJMenuItem()); + } setJMenuBar(bar); pack(); setLocationRelativeTo(owner); } - private GraphDialog setColumnInfo(ValueTable.ColumnInfo[] columnInfo) { + GraphDialog setColumnInfo(ValueTable.ColumnInfo[] columnInfo) { this.columnInfo = columnInfo; return this; } diff --git a/src/main/java/de/neemann/digital/gui/components/data/ScopeTrigger.java b/src/main/java/de/neemann/digital/gui/components/data/ScopeTrigger.java index 1699fbb45..0831b8710 100644 --- a/src/main/java/de/neemann/digital/gui/components/data/ScopeTrigger.java +++ b/src/main/java/de/neemann/digital/gui/components/data/ScopeTrigger.java @@ -25,29 +25,50 @@ import java.util.ArrayList; import java.util.List; import static de.neemann.digital.core.element.PinInfo.input; +import static de.neemann.digital.gui.components.data.GraphDialog.createColumnsInfo; /** * The ScopeElement */ public class ScopeTrigger extends Node implements Element { + /** + * Trigger mode + */ + public enum Trigger { + /** + * rising edge + */ + rising, + /** + * falling edge + */ + falling, + /** + * both edges + */ + both + } + /** * The ScopeElement description */ public static final ElementTypeDescription DESCRIPTION = new ElementTypeDescription(ScopeTrigger.class, input("T").setClock()) .addAttribute(Keys.LABEL) + .addAttribute(Keys.TRIGGER) .addAttribute(Keys.MAX_STEP_COUNT); private final int maxSize; private final String label; + private final Trigger trigger; private ObservableValue clockValue; private boolean lastClock; private ValueTable logData; private ArrayList signals; private Model model; private GraphDialog graphDialog; - private boolean clockHasChanged; + private boolean wasTrigger; private ScopeModelStateObserver scopeModelStateObserver; /** @@ -58,6 +79,7 @@ public class ScopeTrigger extends Node implements Element { public ScopeTrigger(ElementAttributes attr) { label = attr.getLabel(); maxSize = attr.get(Keys.MAX_STEP_COUNT); + trigger = attr.get(Keys.TRIGGER); } @Override @@ -68,8 +90,18 @@ public class ScopeTrigger extends Node implements Element { @Override public void readInputs() throws NodeException { boolean clock = clockValue.getBool(); - if (clock != lastClock) - clockHasChanged = true; + if (clock != lastClock) { + switch (trigger) { + case rising: + wasTrigger = !lastClock & clock; + break; + case falling: + wasTrigger = lastClock & !clock; + break; + default: + wasTrigger = true; + } + } lastClock = clock; } @@ -112,20 +144,22 @@ public class ScopeTrigger extends Node implements Element { private final class ScopeModelStateObserver implements ModelStateObserver { @Override public void handleEvent(ModelEvent event) { - if (clockHasChanged && event.getType() == ModelEventType.STEP) { + if (wasTrigger && event.getType() == ModelEventType.STEP) { Value[] sample = new Value[logData.getColumns()]; for (int i = 0; i < logData.getColumns(); i++) sample[i] = new Value(signals.get(i).getValue()); logData.add(new TestRow(sample)); - clockHasChanged = false; + wasTrigger = false; if (graphDialog == null || !graphDialog.isVisible()) { SwingUtilities.invokeLater(() -> { String title = label; if (title.isEmpty()) title = Lang.get("elem_ScopeTrigger_short"); - graphDialog = new GraphDialog(model.getWindowPosManager().getMainFrame(), title, logData); + graphDialog = new GraphDialog(model.getWindowPosManager().getMainFrame(), title, logData, model, false) + .setColumnInfo(createColumnsInfo(signals)); + graphDialog.addWindowListener(new WindowAdapter() { @Override public void windowClosed(WindowEvent e) { diff --git a/src/main/resources/lang/lang_de.xml b/src/main/resources/lang/lang_de.xml index be89eee3b..8cc984f3c 100644 --- a/src/main/resources/lang/lang_de.xml +++ b/src/main/resources/lang/lang_de.xml @@ -181,7 +181,7 @@ die Überschrift. Messwert - Ein Messwert, welcher im Messwertgraphen bzw. in der Messwertetabelle dargestellt wird. + Ein Messwert, welcher im Messwertegraphen bzw. in der Messwertetabelle dargestellt wird. Dieses Element kann verwendet werden, um auf einfache Weise Werte aus eingebetteten Schaltungen zu beobachten. Hat keine weitere Funktion für die Simulation. @@ -238,14 +238,14 @@ Jedes Bit in diesem Datenwort repräsentiert den Zustand einer Zeile der aktuellen Spalte. Die Nummer der aktuellen Spalte, dessen Zustand gerade am anderen Eingang anliegt. - Messwertgraph - Zeigt einen Messwertgraphen innerhalb des Schaltkreisbereichs. + Messwertegraph + Zeigt einen Messwertegraphen innerhalb des Schaltkreisbereichs. Es können sowohl komplette Taktschritte als auch einzelne Gatter-Veränderungen angezeigt werden. Hat keine weitere Funktion für die Simulation. - Getriggerter Messwertgraph + Getriggerter Messwertegraph Scope - Zeigt einen Messwertgraph, wobei nur dann Messwerte gespeichert werden, + Zeigt einen Messwertegraph, wobei nur dann Messwerte gespeichert werden, wenn sich das Eingangssignal verändert. Das Speichern findet statt, wenn sich die Schaltung stabilisiert hat. Der Trigger startet nicht die Messung wie bei einem echten Scope, sondern jedes Triggerereignis @@ -1316,7 +1316,7 @@ Sind evtl. die Namen der Variablen nicht eindeutig? Wenn eingeschaltet, wird beim Start der Schaltung der Echtzeittakt gestartet. Zeige Messwertegraph bei Simulationsstart Beim Start der Simulation wird ein Graph mit den Messwerten angezeigt. - Zeige Messwertgraph im Gatterschrittmodus bei Simulationsstart + Zeige Messwertegraph im Gatterschrittmodus bei Simulationsstart Beim Start der Simulation wird ein Graph mit den Messwerten im Gatterschrittmodus angezeigt. Dabei werden alle Gatterwechsel angezeigt. Im Messwertegraph anzeigen @@ -1602,6 +1602,12 @@ Sind evtl. die Namen der Variablen nicht eindeutig? Wird vom Layout-Shape verwendet. Legt den Abstand zum vorherigen Pin fest. + Trigger + Triggerbedingung für die Datenaufzeichnung. + steigende Flanke + fallende Flanke + beide Flanken + Farbschema Normal Dunkel diff --git a/src/main/resources/lang/lang_en.xml b/src/main/resources/lang/lang_en.xml index 9921b6433..4d21cf30f 100644 --- a/src/main/resources/lang/lang_en.xml +++ b/src/main/resources/lang/lang_en.xml @@ -1588,6 +1588,12 @@ Used by the layout shape type. Sets the distance to the previous pin. + Trigger + Trigger condition for data recording. + rising edge + falling edge + both edges + Color scheme Normal Dark