adds a attribute to select the trigger mode

This commit is contained in:
hneemann 2020-12-05 17:28:23 +01:00
parent ac0d9db8be
commit e6bf2658ac
5 changed files with 86 additions and 29 deletions

View File

@ -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<TestCaseDescription> TESTDATA =
new Key<>("Testdata", TestCaseDescription::new);
/**
* The scope trigger mode
*/
public static final Key.KeyEnum<ScopeTrigger.Trigger> TRIGGER =
new Key.KeyEnum<>("trigger", ScopeTrigger.Trigger.both, ScopeTrigger.Trigger.values());
}

View File

@ -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<Signal> signals) {
static ValueTable.ColumnInfo[] createColumnsInfo(ArrayList<Signal> 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;
}

View File

@ -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<Signal> 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) {

View File

@ -181,7 +181,7 @@
die Überschrift.
</string>
<string name="elem_Probe">Messwert</string>
<string name="elem_Probe_tt">Ein Messwert, welcher im Messwertgraphen bzw. in der Messwertetabelle dargestellt wird.
<string name="elem_Probe_tt">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.
</string>
@ -238,14 +238,14 @@
Jedes Bit in diesem Datenwort repräsentiert den Zustand einer Zeile der aktuellen Spalte.
</string>
<string name="elem_LedMatrix_pin_c-addr">Die Nummer der aktuellen Spalte, dessen Zustand gerade am anderen Eingang anliegt.</string>
<string name="elem_Data">Messwertgraph</string>
<string name="elem_Data_tt">Zeigt einen Messwertgraphen innerhalb des Schaltkreisbereichs.
<string name="elem_Data">Messwertegraph</string>
<string name="elem_Data_tt">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.
</string>
<string name="elem_ScopeTrigger">Getriggerter Messwertgraph</string>
<string name="elem_ScopeTrigger">Getriggerter Messwertegraph</string>
<string name="elem_ScopeTrigger_short">Scope</string>
<string name="elem_ScopeTrigger_tt">Zeigt einen Messwertgraph, wobei nur dann Messwerte gespeichert werden,
<string name="elem_ScopeTrigger_tt">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?</string>
<string name="key_runRealTime_tt">Wenn eingeschaltet, wird beim Start der Schaltung der Echtzeittakt gestartet.</string>
<string name="key_showDataGraph">Zeige Messwertegraph bei Simulationsstart</string>
<string name="key_showDataGraph_tt">Beim Start der Simulation wird ein Graph mit den Messwerten angezeigt.</string>
<string name="key_showDataGraphMicro">Zeige Messwertgraph im Gatterschrittmodus bei Simulationsstart</string>
<string name="key_showDataGraphMicro">Zeige Messwertegraph im Gatterschrittmodus bei Simulationsstart</string>
<string name="key_showDataGraphMicro_tt">Beim Start der Simulation wird ein Graph mit den Messwerten im Gatterschrittmodus
angezeigt. Dabei werden alle Gatterwechsel angezeigt.</string>
<string name="key_addValueToGraph">Im Messwertegraph anzeigen</string>
@ -1602,6 +1602,12 @@ Sind evtl. die Namen der Variablen nicht eindeutig?</string>
<string name="key_layoutShapeDelta_tt">Wird vom Layout-Shape verwendet. Legt den Abstand zum vorherigen Pin fest.
</string>
<string name="key_trigger">Trigger</string>
<string name="key_trigger_tt">Triggerbedingung für die Datenaufzeichnung.</string>
<string name="key_trigger_rising">steigende Flanke</string>
<string name="key_trigger_falling">fallende Flanke</string>
<string name="key_trigger_both">beide Flanken</string>
<string name="key_colorScheme">Farbschema</string>
<string name="key_colorScheme_DEFAULT">Normal</string>
<string name="key_colorScheme_DARK">Dunkel</string>

View File

@ -1588,6 +1588,12 @@
<string name="key_layoutShapeDelta_tt">Used by the layout shape type. Sets the distance to the previous pin.
</string>
<string name="key_trigger">Trigger</string>
<string name="key_trigger_tt">Trigger condition for data recording.</string>
<string name="key_trigger_rising">rising edge</string>
<string name="key_trigger_falling">falling edge</string>
<string name="key_trigger_both">both edges</string>
<string name="key_colorScheme">Color scheme</string>
<string name="key_colorScheme_DEFAULT">Normal</string>
<string name="key_colorScheme_DARK">Dark</string>