updates that were lying around but never got checked in; includes reorg of gui
[slipway.git] / src / com / atmel / fpslic / FpslicBoard.java
diff --git a/src/com/atmel/fpslic/FpslicBoard.java b/src/com/atmel/fpslic/FpslicBoard.java
new file mode 100644 (file)
index 0000000..4016b60
--- /dev/null
@@ -0,0 +1,139 @@
+package com.atmel.fpslic;
+
+import edu.berkeley.abits.*;
+import java.io.*;
+
+/**
+ * Implementation of <tt>Board</tt> for Fpslic devices; subclass must
+ * implement methods to wiggle pins on the chip.
+ */
+public abstract class FpslicBoard implements Board {
+
+    public FpslicBoard() throws IOException { }
+
+    public void reset() throws IOException {
+        avrrstPin(false);
+        configDataPin(false);
+        resetPin(false);
+        cclkPin(false);
+        
+        conPin(false);
+        flush();
+
+        resetPin(false);
+        try { Thread.sleep(500); } catch (Exception e) { }
+        if (initPin()) throw new IOException("INIT was still high after pulling RESET low");
+
+        resetPin(true);
+        try { Thread.sleep(500); } catch (Exception e) { }
+        if (!initPin()) throw new IOException("INIT was still low after releasing RESET");
+
+        sendConfigBits(0,2);
+        flush();
+    }
+
+    public OutputStream getConfigStream() throws IOException {
+        reset();
+        return new OutputStream() {
+                int bytes = 0;
+                int bits = 0;
+                public void write(int in) throws IOException {
+                    for(int i=7; i>=0; i--) {
+                        bits++;
+                        sendConfigBits((((in & 0xff) & (1<<i))!=0)?1:0, 1);
+                    }
+                }
+                public void write(byte[] b, int off, int len) throws IOException {
+                    for(int i=off; i<off+len; i++)
+                        write(b[i]);
+                }
+                public void flush() throws IOException {
+                    FpslicBoard.this.flush();
+                }
+                public void close() throws IOException {
+                    flush();
+                    releaseConPin();
+                    if (!initPin())
+                        throw new IOException("initialization failed at " + bytes);
+                    for(int i=0; i<100; i++) {
+                        flush();
+                        if (!initPin())
+                            throw new IOException("initialization failed at " + bytes);
+                        try { Thread.sleep(20); } catch (Exception e) { }
+                        sendConfigBits(0,1);
+                    }
+                    FpslicBoard.this.close();
+                }
+            };
+    }
+
+    public void selfTest(SelfTestResultListener resultListener) throws IOException {
+        boolean pin;
+
+        // correct preamble
+        getConfigStream();
+        sendConfigBits(Integer.parseInt("00000000", 2), 8);
+        sendConfigBits(Integer.parseInt("10110111", 2), 8);
+        sendConfigBits(0,1);
+        flush();
+        try { Thread.sleep(100); } catch (Exception e) { }
+        pin = initPin();
+        resultListener.reportTestResult(0, 4, pin);
+
+        // preamble shifted one bit earlier than it should be
+        getConfigStream();
+        sendConfigBits(Integer.parseInt("0000000",  2), 7);
+        sendConfigBits(Integer.parseInt("10110111", 2), 8);
+        sendConfigBits(0, 2);
+        flush();
+        try { Thread.sleep(100); } catch (Exception e) { }
+        pin = initPin();
+        resultListener.reportTestResult(1, 4, !pin);
+
+        // preamble shifted one bit later than it should be
+        getConfigStream();
+        sendConfigBits(Integer.parseInt("000000000", 2), 9);
+        sendConfigBits(Integer.parseInt("10110111",  2), 8);
+        //sendConfigBits(0, 1);
+        flush();
+        try { Thread.sleep(100); } catch (Exception e) { }
+        pin = initPin();
+        resultListener.reportTestResult(2, 4, !pin);
+
+        // plain 'ol bogus preamble
+        getConfigStream();
+        sendConfigBits(Integer.parseInt("00000000", 2), 8);
+        sendConfigBits(Integer.parseInt("11110111", 2), 8);
+        sendConfigBits(0, 1);
+        flush();
+        try { Thread.sleep(100); } catch (Exception e) { }
+        pin = initPin();
+        resultListener.reportTestResult(3, 4, !pin);
+    }
+
+    ////////////////////////////////////////////////////////////////////////////////
+
+    private void sendConfigBits(int bits, int numbits) throws IOException {
+        for(int i=(numbits-1); i>=0; i--) {
+            boolean bit = (bits & (1<<i)) != 0;
+            configDataPin(bit);
+            cclkPin(true);
+            cclkPin(false);
+        }
+    }
+
+    ////////////////////////////////////////////////////////////////////////////////
+
+    protected abstract void    avrrstPin(boolean on)      throws IOException;
+    protected abstract void    cclkPin(boolean on)        throws IOException;
+    protected abstract void    configDataPin(boolean on)  throws IOException;
+    protected abstract void    resetPin(boolean on)       throws IOException;
+    protected abstract boolean initPin()                  throws IOException;
+    protected abstract void    releaseConPin()            throws IOException;
+    protected abstract void    conPin(boolean on)         throws IOException;
+
+    protected abstract void    purge()                    throws IOException;
+    protected abstract void    flush()                    throws IOException;
+    protected abstract void    close()                    throws IOException;
+
+}