From 04de28b577f557632854a5caad41195cc36ec9d0 Mon Sep 17 00:00:00 2001 From: hneemann Date: Mon, 26 Jun 2017 13:07:12 +0200 Subject: [PATCH] added "active low" option to button. --- .../de/neemann/digital/core/element/Keys.java | 6 ++++ .../de/neemann/digital/core/io/Button.java | 30 ++++++++++++++++++- .../digital/draw/shapes/ButtonShape.java | 23 +++++--------- src/main/resources/lang/lang_de.xml | 6 ++-- src/main/resources/lang/lang_en.xml | 6 ++-- 5 files changed, 51 insertions(+), 20 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 5716b596b..25c27f376 100644 --- a/src/main/java/de/neemann/digital/core/element/Keys.java +++ b/src/main/java/de/neemann/digital/core/element/Keys.java @@ -390,4 +390,10 @@ public final class Keys { public static final Key FET_UNIDIRECTIONAL = new Key<>("unidirectional", false); + /** + * true if component is active low + */ + public static final Key ACTIVE_LOW + = new Key<>("activeLow", false); + } diff --git a/src/main/java/de/neemann/digital/core/io/Button.java b/src/main/java/de/neemann/digital/core/io/Button.java index 030e92772..5a0ed8b62 100644 --- a/src/main/java/de/neemann/digital/core/io/Button.java +++ b/src/main/java/de/neemann/digital/core/io/Button.java @@ -19,10 +19,13 @@ public class Button implements Element { */ public static final ElementTypeDescription DESCRIPTION = new ElementTypeDescription(Button.class) .addAttribute(Keys.ROTATE) - .addAttribute(Keys.LABEL); + .addAttribute(Keys.LABEL) + .addAttribute(Keys.ACTIVE_LOW); private final ObservableValue output; private final String label; + private final Boolean invert; + private boolean pressed; /** * Creates a new instance @@ -32,6 +35,8 @@ public class Button implements Element { public Button(ElementAttributes attributes) { output = new ObservableValue("out", 1).setPinDescription(DESCRIPTION); label = attributes.get(Keys.LABEL); + invert = attributes.get(Keys.ACTIVE_LOW); + output.setValue(invert ? 1 : 0); } @Override @@ -48,4 +53,27 @@ public class Button implements Element { public void registerNodes(Model model) { model.addSignal(new Signal(label, output)); } + + /** + * Sets the buttons state + * + * @param pressed true if pressed + */ + public void setPressed(boolean pressed) { + if (pressed != this.pressed) { + this.pressed = pressed; + if (pressed ^ invert) { + output.setValue(1); + } else { + output.setValue(0); + } + } + } + + /** + * @return true if pressed + */ + public boolean isPressed() { + return pressed; + } } diff --git a/src/main/java/de/neemann/digital/draw/shapes/ButtonShape.java b/src/main/java/de/neemann/digital/draw/shapes/ButtonShape.java index e715f1d38..f76ed8491 100644 --- a/src/main/java/de/neemann/digital/draw/shapes/ButtonShape.java +++ b/src/main/java/de/neemann/digital/draw/shapes/ButtonShape.java @@ -1,10 +1,10 @@ package de.neemann.digital.draw.shapes; -import de.neemann.digital.core.ObservableValue; import de.neemann.digital.core.Observer; import de.neemann.digital.core.element.Element; import de.neemann.digital.core.element.ElementAttributes; import de.neemann.digital.core.element.PinDescriptions; +import de.neemann.digital.core.io.Button; import de.neemann.digital.draw.elements.IOState; import de.neemann.digital.draw.elements.Pin; import de.neemann.digital.draw.elements.Pins; @@ -28,7 +28,7 @@ public class ButtonShape implements Shape { private final String label; private final PinDescriptions outputs; - private IOState ioState; + private Button button; /** * Creates a new instance @@ -49,7 +49,7 @@ public class ButtonShape implements Shape { @Override public InteractorInterface applyStateMonitor(IOState ioState, Observer guiObserver) { - this.ioState = ioState; + this.button = (Button) ioState.getElement(); ioState.getOutput(0).addObserverToValue(guiObserver); return new InteractorInterface() { @Override @@ -59,19 +59,13 @@ public class ButtonShape implements Shape { @Override public boolean pressed(CircuitComponent cc, Point pos, IOState ioState, Element element, Sync modelSync) { - modelSync.access(() -> { - ObservableValue value = ioState.getOutput(0); - value.setValue(1); - }); + modelSync.access(() -> button.setPressed(true)); return true; } @Override public boolean released(CircuitComponent cc, Point pos, IOState ioState, Element element, Sync modelSync) { - modelSync.access(() -> { - ObservableValue value = ioState.getOutput(0); - value.setValue(0); - }); + modelSync.access(() -> button.setPressed(false)); return true; } @@ -84,10 +78,10 @@ public class ButtonShape implements Shape { @Override public void drawTo(Graphic graphic, Style heighLight) { - boolean down = false; - if (ioState != null) down = ioState.getOutput(0).getBool(); + boolean isPressed = false; + if (button != null) isPressed = button.isPressed(); - if (down) { + if (isPressed) { graphic.drawPolygon(new Polygon(true) .add(-SIZE * 2 - 1, -SIZE) .add(-1, -SIZE) @@ -109,7 +103,6 @@ public class ButtonShape implements Shape { graphic.drawLine(new Vector(-1 - HEIGHT, SIZE - HEIGHT), new Vector(-1 - t, SIZE - t), Style.NORMAL); } - Vector textPos = new Vector(-SIZE * 3, -4); graphic.drawText(textPos, textPos.add(1, 0), label, Orientation.RIGHTCENTER, Style.NORMAL); } diff --git a/src/main/resources/lang/lang_de.xml b/src/main/resources/lang/lang_de.xml index 25bad778f..7b42158e5 100644 --- a/src/main/resources/lang/lang_de.xml +++ b/src/main/resources/lang/lang_de.xml @@ -67,8 +67,8 @@ Dieses Element kann verwendet werden, um einen Assemblerbefehl BRK zu implementieren. Es kann dann ein Programm bis zum nächsten BRK-Befehl ausgeführt werden. Taster - Ein einfacher Taster, welcher in seinen Ausgangszustand (0) zurückkehrt wenn er nicht gehalten wird. Am Ausgang liegt eine 1 an solange der Taster gedrückt ist. - Gibt 1 zurück wenn gedrückt, sonst 0. Setzt sich auf 0 zurück wenn nicht gehalten. + Ein einfacher Taster, welcher in seinen Ausgangszustand zurückkehrt wenn er nicht gehalten wird. + Das Ausgangssignal des Tasters. Takteingang Wechselt im vorgegebenen Takt zwischen 0 und 1. Ein Takstignal. Dieses Taksignal kann über die Echtzeituhr gesteuert werden. Die Taktfrequenz kann im Attribute-Dialog eingestellt werden. @@ -676,6 +676,8 @@ Sind evtl. die Namen der Variablen nicht eindeutig? schneller simuliert werden, als bidirektionale Transistoren. Da es keine Rückwirkung von Drain zu Source gibt, können Transistoren in diesem Modus auch keine Kurzschlüsse über die Drain-Source Strecke verursachen. Daher kann dieser Modus in manchen CMOS-Schaltungen erforderlich sein. + Active Low + Wenn gesetzt, ist der Ausgang im aktiven Zustand Low. Leitung eingefügt. Aus Zwischenablage eingefügt. diff --git a/src/main/resources/lang/lang_en.xml b/src/main/resources/lang/lang_en.xml index eaff53393..cc46607ea 100644 --- a/src/main/resources/lang/lang_en.xml +++ b/src/main/resources/lang/lang_en.xml @@ -67,8 +67,8 @@ You can use the component to implement a BRK assembly instruction. Then you can run a simulated processor until a BRK instruction is reached. Button - A simple button which resets back to its original state (0) when not held down. Outputs a 1 if held down. - Returns 1 if pressed else 0. Resets back to 0 when not held down. + A simple button which resets back to its original state when not held down. + The output signal of the button. Clock Input Alternates 0 and 1 with the set clock speed. A clock signal. Its possible to control it by the real time clock. Clock speed (in Hz) can be set in attributes dialog. @@ -665,6 +665,8 @@ The names of the variables may not be unique. much faster to simulate than bidirectional transistors. Since there is no feedback from drain to source, in this mode, the transistor can not short the connected wires when it is conducting. Thus, this mode is necessary to simulate certain CMOS circuits. + Active Low + If selected the output is low if the component is active. Inserted wire. Insert from clipboard.