mirror of
https://github.com/hneemann/Digital.git
synced 2025-09-18 01:14:42 -04:00
reworked seven segment flicker suppression; see #829
This commit is contained in:
parent
4bce1db132
commit
d2b1b910f2
@ -618,6 +618,14 @@ public final class Keys {
|
||||
public static final Key<Boolean> LED_PERSISTENCE
|
||||
= new Key<>("ledPersistence", false).allowGroupEdit().setDependsOn(COMMON_CONNECTION);
|
||||
|
||||
/**
|
||||
* Used to enable the storage of the last state in the Seven Seg display.
|
||||
*/
|
||||
public static final Key<Integer> LED_PERSIST_TIME
|
||||
= new Key.KeyInteger("persistTime", 0)
|
||||
.setMin(0)
|
||||
.allowGroupEdit();
|
||||
|
||||
/**
|
||||
* Fitter for the atf15xx
|
||||
*/
|
||||
|
@ -158,7 +158,7 @@ public class Out implements Element {
|
||||
addAttribute(Keys.COLOR);
|
||||
addAttribute(Keys.COMMON_CONNECTION);
|
||||
addAttribute(Keys.COMMON_CONNECTION_TYPE);
|
||||
addAttribute(Keys.LED_PERSISTENCE);
|
||||
addAttribute(Keys.LED_PERSIST_TIME);
|
||||
}
|
||||
|
||||
@Override
|
||||
|
@ -30,12 +30,12 @@ import static de.neemann.digital.draw.shapes.GenericShape.SIZE2;
|
||||
public class SevenSegShape extends SevenShape {
|
||||
private final PinDescriptions inputPins;
|
||||
private final boolean commonConnection;
|
||||
private final boolean persistence;
|
||||
private final int persistenceTime;
|
||||
private final boolean anode;
|
||||
private LEDState[] ledStates;
|
||||
private final boolean[] displayStates;
|
||||
private Pins pins;
|
||||
private SegmentUpdater segmentUpdater;
|
||||
private PersistenceHandler persistenceHandler;
|
||||
|
||||
/**
|
||||
* Creates a new instance
|
||||
@ -49,7 +49,7 @@ public class SevenSegShape extends SevenShape {
|
||||
this.inputPins = inputs;
|
||||
commonConnection = attr.get(Keys.COMMON_CONNECTION);
|
||||
anode = attr.get(Keys.COMMON_CONNECTION_TYPE).equals(CommonConnectionType.anode);
|
||||
persistence = attr.get(Keys.LED_PERSISTENCE);
|
||||
persistenceTime = attr.get(Keys.LED_PERSIST_TIME);
|
||||
displayStates = new boolean[8];
|
||||
}
|
||||
|
||||
@ -74,23 +74,25 @@ public class SevenSegShape extends SevenShape {
|
||||
@Override
|
||||
public Interactor applyStateMonitor(IOState ioState) {
|
||||
ledStates = new LEDState[8];
|
||||
for (int i = 0; i < 8; i++)
|
||||
ledStates[i] = createLEDState(i, ioState.getInputs());
|
||||
for (int i = 0; i < 8; i++) {
|
||||
LEDState ledState = createLEDState(i, ioState.getInputs());
|
||||
if (persistenceTime == 0)
|
||||
ledStates[i] = ledState;
|
||||
else
|
||||
ledStates[i] = persistenceHandler.persist(ledState, persistenceTime);
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void registerModel(ModelCreator modelCreator, Model model, ModelEntry element) {
|
||||
if (commonConnection && persistence)
|
||||
segmentUpdater = model.getOrCreateObserver(SegmentUpdater.class, SegmentUpdater::new);
|
||||
if (persistenceTime > 0)
|
||||
persistenceHandler = model.getOrCreateObserver(PersistenceHandler.class, PersistenceHandler::new);
|
||||
}
|
||||
|
||||
private LEDState createLEDState(int i, ObservableValues inputs) {
|
||||
if (commonConnection) {
|
||||
if (persistence) {
|
||||
return new CommonConnectionPersist(inputs.get(i), inputs.get(8), segmentUpdater);
|
||||
} else
|
||||
return new CommonConnection(inputs.get(i), inputs.get(8));
|
||||
return new CommonConnection(inputs.get(i), inputs.get(8), anode);
|
||||
} else {
|
||||
ObservableValue in = inputs.get(i);
|
||||
return () -> !in.isHighZ() && in.getBool();
|
||||
@ -125,71 +127,71 @@ public class SevenSegShape extends SevenShape {
|
||||
boolean getState();
|
||||
}
|
||||
|
||||
//CHECKSTYLE.OFF: FinalClass
|
||||
private class CommonConnection implements LEDState {
|
||||
private static final class CommonConnection implements LEDState {
|
||||
private final ObservableValue led;
|
||||
private final ObservableValue cc;
|
||||
private final boolean anode;
|
||||
|
||||
private CommonConnection(ObservableValue led, ObservableValue cc) {
|
||||
private CommonConnection(ObservableValue led, ObservableValue cc, boolean anode) {
|
||||
this.led = led;
|
||||
this.cc = cc;
|
||||
}
|
||||
|
||||
protected boolean isOn() {
|
||||
return (led.getBool() != cc.getBool()) && (led.getBool() ^ anode);
|
||||
}
|
||||
|
||||
protected boolean isHighZ() {
|
||||
return led.isHighZ() || cc.isHighZ();
|
||||
this.anode = anode;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean getState() {
|
||||
return !isHighZ() && isOn();
|
||||
boolean highZ = led.isHighZ() || cc.isHighZ();
|
||||
boolean on = (led.getBool() != cc.getBool()) && (led.getBool() ^ anode);
|
||||
return !highZ && on;
|
||||
}
|
||||
}
|
||||
//CHECKSTYLE.ON: FinalClass
|
||||
|
||||
private final class CommonConnectionPersist extends CommonConnection {
|
||||
private boolean led;
|
||||
private static final class PersistenceOfVision implements LEDState {
|
||||
private final LEDState parent;
|
||||
private final int persistenceTime;
|
||||
private int timeVisible;
|
||||
|
||||
private CommonConnectionPersist(ObservableValue led, ObservableValue cc, SegmentUpdater segmentUpdater) {
|
||||
super(led, cc);
|
||||
segmentUpdater.add(this);
|
||||
private PersistenceOfVision(LEDState parent, int persistenceTime) {
|
||||
this.parent = parent;
|
||||
this.persistenceTime = persistenceTime;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean getState() {
|
||||
return led;
|
||||
return timeVisible > 0;
|
||||
}
|
||||
|
||||
public void updateState() {
|
||||
if (!isHighZ())
|
||||
led = isOn();
|
||||
public void check() {
|
||||
if (parent.getState())
|
||||
timeVisible = persistenceTime;
|
||||
if (timeVisible > 0)
|
||||
timeVisible--;
|
||||
}
|
||||
}
|
||||
|
||||
private static final class SegmentUpdater implements ModelStateObserverTyped {
|
||||
private final ArrayList<CommonConnectionPersist> segments;
|
||||
private static final class PersistenceHandler implements ModelStateObserverTyped {
|
||||
private final ArrayList<PersistenceOfVision> segments;
|
||||
|
||||
private SegmentUpdater() {
|
||||
private PersistenceHandler() {
|
||||
segments = new ArrayList<>();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void handleEvent(ModelEvent event) {
|
||||
if (event.getType() == ModelEventType.STEP)
|
||||
for (CommonConnectionPersist c : segments)
|
||||
c.updateState();
|
||||
if (event.getType() == ModelEventType.STEP || event.getType() == ModelEventType.CHECKBURN)
|
||||
for (PersistenceOfVision ag : segments)
|
||||
ag.check();
|
||||
}
|
||||
|
||||
@Override
|
||||
public ModelEventType[] getEvents() {
|
||||
return new ModelEventType[]{ModelEventType.STEP};
|
||||
return new ModelEventType[]{ModelEventType.STEP, ModelEventType.CHECKBURN};
|
||||
}
|
||||
|
||||
public void add(CommonConnectionPersist commonConnectionPersist) {
|
||||
segments.add(commonConnectionPersist);
|
||||
public PersistenceOfVision persist(LEDState state, int persistenceTime) {
|
||||
PersistenceOfVision ag = new PersistenceOfVision(state, persistenceTime);
|
||||
segments.add(ag);
|
||||
return ag;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -1678,6 +1678,9 @@ Sind evtl. die Namen der Variablen nicht eindeutig?</string>
|
||||
<string name="key_probeMode_DOWN">Zähle fallende Flanken</string>
|
||||
<string name="key_probeMode_BOTH">Zähle beide Flanken</string>
|
||||
|
||||
<string name="key_persistTime">Nachleuchten</string>
|
||||
<string name="key_persistTime_tt">Gibt die Dauer des Nachleuchtens an. Je größer der Wert, je länger die Nachleuchtdauer.</string>
|
||||
|
||||
<string name="key_telnetEscape">Telnet-Modus</string>
|
||||
<string name="key_telnetEscape_tt">Wenn gesetzt, werden die Telnet Steuerkommandos ausgewertet.
|
||||
Zusätzlich werden vom Server die Kommandos SGA und ECHO gesendet.
|
||||
|
@ -1661,6 +1661,9 @@
|
||||
<string name="key_probeMode_DOWN">Count on Falling Edge</string>
|
||||
<string name="key_probeMode_BOTH">Count both Edges</string>
|
||||
|
||||
<string name="key_persistTime">Persistence Of Vision</string>
|
||||
<string name="key_persistTime_tt">Specifies the duration of the afterglow. The larger the value, the longer the afterglow duration.</string>
|
||||
|
||||
<string name="key_telnetEscape">Telnet mode</string>
|
||||
<string name="key_telnetEscape_tt">If set, the Telnet control commands are evaluated.
|
||||
In addition, the server sends the SGA and ECHO commands. If this option is disabled,
|
||||
|
Loading…
x
Reference in New Issue
Block a user