Bladeren bron

Begin adding code to traverse states

Fabio Battaglia 4 jaren geleden
bovenliggende
commit
fbe6522320

+ 1 - 1
src/main/java/info/hkzlab/dupal/analyzer/exceptions/DuPALAnalyzerException.java

@@ -1,6 +1,6 @@
 package info.hkzlab.dupal.analyzer.exceptions;
 
-public class DuPALAnalyzerException extends IllegalStateException {
+public class DuPALAnalyzerException extends Exception {
     private static final long serialVersionUID = 1L;
 
     public DuPALAnalyzerException(String message) {

+ 63 - 9
src/main/java/info/hkzlab/dupal/analyzer/palanalisys/explorers/OSExplorer.java

@@ -1,13 +1,22 @@
 package info.hkzlab.dupal.analyzer.palanalisys.explorers;
 
+import java.util.ArrayList;
+import java.util.Currency;
+import java.util.HashMap;
+import java.util.Map;
+
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
 
 import info.hkzlab.dupal.analyzer.board.boardio.DuPALCmdInterface;
 import info.hkzlab.dupal.analyzer.devices.PALSpecs;
+import info.hkzlab.dupal.analyzer.exceptions.DuPALAnalyzerException;
 import info.hkzlab.dupal.analyzer.exceptions.DuPALBoardException;
+import info.hkzlab.dupal.analyzer.palanalisys.graph.GraphLink;
+import info.hkzlab.dupal.analyzer.palanalisys.graph.OutLink;
 import info.hkzlab.dupal.analyzer.palanalisys.graph.OutState;
 import info.hkzlab.dupal.analyzer.palanalisys.graph.OutStatePins;
+import info.hkzlab.dupal.analyzer.palanalisys.graph.PathFinder;
 import info.hkzlab.dupal.analyzer.utilities.BitUtils;
 
 public class OSExplorer {
@@ -15,36 +24,81 @@ public class OSExplorer {
 
     private OSExplorer() {};
 
-    public static void exploreOutStates(final DuPALCmdInterface dpci, final int ioAsOutMask) throws DuPALBoardException {
+    public static void exploreOutStates(final DuPALCmdInterface dpci, final int ioAsOutMask) throws DuPALBoardException, DuPALAnalyzerException {
+        Map<Integer, OutState> statesMap = new HashMap<>();
         PALSpecs pSpecs = dpci.palSpecs;
         int maxLinks = 1 << (pSpecs.getPinCount_IN() + (pSpecs.getPinCount_IO()-BitUtils.countBits(ioAsOutMask)));
         OutState curState;
 
-        curState = generateOutStateForIdx(dpci, 0, ioAsOutMask, maxLinks);
+        curState = getOutStateForIdx(dpci, 0, ioAsOutMask, maxLinks, statesMap);
         logger.info("exploreOutStates() -> Initial state: " + curState);
 
-        //while(curState != null) {
+        while(curState != null) {
+            // If we ended up in a state where all the links have already been explored...
+            if(curState.isStateFull()) {
+                ArrayList<GraphLink> linkPath = PathFinder.findPathToNearestUnfilledState(curState);
+                if(linkPath != null && !linkPath.isEmpty()) {
+                    for(GraphLink l : linkPath) dpci.write(l.getLinkInputs()); // Walk the path to the new state
+                    curState = (OutState) linkPath.get(linkPath.size() - 1);
+                    logger.info("exploreOutStates() -> walked path to state " + curState);
+
+                    // Do some doublecheckin
+                    int pins = (dpci.read() & ~curState.pins.hiz) & (pSpecs.getMask_O_R() | ioAsOutMask);
+                    int expected_pins = ((curState.pins.out & ~curState.pins.hiz) & (pSpecs.getMask_O_R() | ioAsOutMask));
+                    if(pins != expected_pins) {
+                        logger.error("exploreOutStates() -> Mismatch in expected pins ("+String.format("E:%02X|A:%02X", pins, expected_pins)+") after walink path to state " + curState);
+                        throw new DuPALAnalyzerException("exploreOutStates() -> Mismatch in expected pins after walking to state " + curState)
+                    }
+                    continue; // Loop again
+
+                } else break; // We're done: can't move to anywhere else
+            }
+
 
-        //}
+
+            int nextIdx = curState.getNextLinkIdx();
+            OutState nOutState = getOutStateForIdx(dpci, nextIdx, ioAsOutMask, maxLinks, statesMap);
+
+            int w_idx = calcolateWriteINFromIdx(nextIdx, pSpecs, ioAsOutMask);
+            curState.addOutLink(new OutLink(curState, nOutState, w_idx));
+
+            curState = nOutState;
+        }
     }
 
-    private static OutState generateOutStateForIdx(final DuPALCmdInterface dpci, final int idx, final int ioAsOutMask, int maxLinks)
+    private static int calcolateWriteINFromIdx(int idx, PALSpecs pSpecs, int ioAsOutMask) {
+        int ioAsOut_W = BitUtils.scatterBitField(BitUtils.consolidateBitField(ioAsOutMask, pSpecs.getMask_IO_R()), pSpecs.getMask_IO_W());
+        int w_idx = BitUtils.scatterBitField(idx, pSpecs.getMask_IN());
+        w_idx |= BitUtils.scatterBitField((idx >> pSpecs.getPinCount_IN()), pSpecs.getMask_IO_W() & ~ioAsOut_W);
+
+
+        return w_idx;
+    }
+
+    private static OutState getOutStateForIdx(final DuPALCmdInterface dpci, final int idx, final int ioAsOutMask, final int maxLinks, final Map<Integer, OutState> statesMap)
             throws DuPALBoardException {
         PALSpecs pSpecs = dpci.palSpecs;
         int ioAsOut_W = BitUtils.scatterBitField(BitUtils.consolidateBitField(ioAsOutMask, pSpecs.getMask_IO_R()), pSpecs.getMask_IO_W());
         int pinState_A, pinState_B;
 
-        int w_idx = BitUtils.scatterBitField(idx, dpci.palSpecs.getMask_IN());
-        w_idx |= BitUtils.scatterBitField((idx >> dpci.palSpecs.getPinCount_IN()), dpci.palSpecs.getMask_IO_W() & ~ioAsOut_W);
+        int w_idx = calcolateWriteINFromIdx(idx, pSpecs, ioAsOutMask);
 
         dpci.write(w_idx);
         pinState_A = dpci.read();
-        dpci.write(w_idx | pSpecs.getMask_O_W() | ioAsOut_W);
+        dpci.write(w_idx | pSpecs.getMask_O_W() | ioAsOut_W); // Try to force the outputs
         pinState_B = dpci.read();
 
+        // TODO: Check that the IOs that we consider as inputs are actually inputs, and are not remaining set to other values (which would mean they're actually outputs)
+
         OutStatePins osp = extractOutPinStates(pSpecs, ioAsOutMask, pinState_A, pinState_B);
 
-        return new OutState(osp, maxLinks);
+        OutState os = new OutState(osp, maxLinks);
+
+        // Check if we already visited this state, in which case, recover that state, otherwise save the state in the map
+        if(statesMap.containsKey(os.hashCode())) os = statesMap.get(os.hashCode());
+        else statesMap.put(os.hashCode(), os);
+
+        return os;
     }
 
     private static OutStatePins extractOutPinStates(PALSpecs pSpecs, int ioAsOutMask, int read_a, int read_b) {