got all intra-CLB switches coded up, but untested
authoradam <adam@megacz.com>
Thu, 9 Mar 2006 13:21:32 +0000 (14:21 +0100)
committeradam <adam@megacz.com>
Thu, 9 Mar 2006 13:21:32 +0000 (14:21 +0100)
Makefile
src/edu/berkeley/obits/AtmelSerial.java
src/edu/berkeley/obits/Device.java
src/edu/berkeley/obits/device/atmel/AT94k.java [new file with mode: 0644]
src/edu/berkeley/obits/device/atmel/At40k.java [new file with mode: 0644]
src/edu/berkeley/obits/device/atmel/AtmelDevice.java
src/edu/berkeley/obits/device/atmel/AvrDrone.java

index 8ab4dc2..bc729bc 100644 (file)
--- a/Makefile
+++ b/Makefile
@@ -9,8 +9,13 @@ led1: obits.jar
             -cp /usr/share/java/RXTXcomm.jar:obits.jar \
             edu.berkeley.obits.AtmelSerial < bitstreams/led1.md4
 
+run: obits.jar
+       java -Djava.library.path=/usr/lib \
+            -cp /usr/share/java/RXTXcomm.jar:obits.jar \
+            edu.berkeley.obits.AtmelSerial
+
 obits.jar: $(shell find src -name \*.java)
-       javac -cp /usr/share/java/RXTXcomm.jar -d build $`
+       javac -cp /usr/share/java/RXTXcomm.jar -d build $(shell find src -name \*.java)
        cd build; jar cvf ../$@ .
 
 # -O3 is required; otherwise the poor AVR can't keep up with us!
index 2a9f352..a7a4dec 100644 (file)
@@ -13,14 +13,16 @@ public class AtmelSerial {
         while(e.hasMoreElements()) {
             CommPortIdentifier cpi = (CommPortIdentifier)e.nextElement();
             Log.info(AtmelSerial.class, "trying " + cpi.getName());
+            if (cpi.getName().startsWith("/dev/cu.usbserial-")) return new RXTXPort(cpi.getName());
+            if (cpi.getName().startsWith("/dev/ttyS0")) return new RXTXPort(cpi.getName());
         }
-        SerialPort ret = new RXTXPort("/dev/ttyS0");
-        Log.info(AtmelSerial.class, "returning " + ret);
-        return ret;
+        Log.info(AtmelSerial.class, "returning null...");
+        return null;
     }
 
     public static void main(String[] s) throws Exception {
         AvrDrone device = new AvrDrone(detectObitsPort());
+        At40k at40k = new At40k.At40k10(device);
         int count = 0;
         try {
             long begin = System.currentTimeMillis();
@@ -34,6 +36,65 @@ public class AtmelSerial {
             device.flush();
             long end = System.currentTimeMillis();
             Log.info(AtmelSerial.class, "finished in " + ((end-begin)/1000) + "s");
+            Thread.sleep(3000);
+            Log.info(AtmelSerial.class, "issuing command");
+
+            //at40k.iob_top(2, true).oe(false);
+            //at40k.iob_top(2, false).oe(false);
+            //at40k.iob_top(1, true).oe(false);
+
+            // this command confirmed to turn *on* led0
+            //at40k.iob_top(1, false).output(0);
+            /*
+            for(int i=0; i<20; i++) {
+                at40k.iob_bot(i, false).output(0);
+                at40k.iob_bot(i, true).output(0);
+            }
+            */
+
+            //System.out.println("tick");
+                //Thread.sleep(3000);
+                //System.out.println("tick");
+                //at40k.cell(0x01, 0x17).xlut((byte)0x);
+
+            at40k.cell(0x04, 0x17).xlut((byte)~0x10);
+            at40k.cell(0x04, 0x17).ylut((byte)0x10);
+            at40k.cell(0x04, 0x17).xo(true);
+
+
+            /*
+            at40k.cell(0x01, 0x17).xin(4);
+            at40k.cell(0x01, 0x17).yin(4);
+            at40k.cell(0x01, 0x16).ylut((byte)0x00);
+            device.mode4(2, 0x17, 0x01, 0);
+
+            for(int i=0; i<10; i++) {
+                Thread.sleep(3000);
+                System.out.println("tick");
+                //at40k.cell(0x01, 0x17).xlut((byte)0xFF);
+                at40k.cell(0x00, 0x17).ylut((byte)0x00);
+                device.flush();
+                Thread.sleep(3000);
+                System.out.println("tick");
+                //at40k.cell(0x01, 0x17).xlut((byte)0x00);
+                at40k.cell(0x00, 0x17).ylut((byte)0xFF);
+                device.flush();
+            }
+            */
+
+
+            /*
+            at40k.iob_top(0, true).output(0);
+            at40k.iob_top(0, true).oe(false);
+            at40k.iob_top(0, true).pullup();
+            device.flush();
+            Thread.sleep(3000);
+
+            Log.info(AtmelSerial.class, "issuing command");
+            at40k.iob_top(1, true).pulldown();
+            device.flush();
+            */
+            Log.info(AtmelSerial.class, "done");
             System.exit(0);
         } catch (Exception e) { e.printStackTrace(); }
     }
index b56114b..a6074ac 100644 (file)
@@ -11,7 +11,7 @@ public interface Device {
     /** flush any commands issued so far, blocking until they have taken effect */
     public void flush() throws DeviceException;
 
-    public static class DeviceException extends Exception {
+    public static class DeviceException extends RuntimeException {
         public DeviceException(String s) { super(s); }
         public DeviceException(Throwable t) { super(t); }
     }
diff --git a/src/edu/berkeley/obits/device/atmel/AT94k.java b/src/edu/berkeley/obits/device/atmel/AT94k.java
new file mode 100644 (file)
index 0000000..e69de29
diff --git a/src/edu/berkeley/obits/device/atmel/At40k.java b/src/edu/berkeley/obits/device/atmel/At40k.java
new file mode 100644 (file)
index 0000000..3d43d75
--- /dev/null
@@ -0,0 +1,257 @@
+package edu.berkeley.obits.device.atmel;
+import static edu.berkeley.obits.device.atmel.AtmelDevice.Constants.*;
+import edu.berkeley.obits.*;
+import org.ibex.util.*;
+
+public class At40k {
+
+    private final AtmelDevice dev;
+    private final int width;
+    private final int height;
+
+    public At40k(AtmelDevice dev, int width, int height) {
+        this.width = width;
+        this.height = height;
+        this.dev = dev;
+    }
+
+    public static class At40k10 extends At40k {
+        public At40k10(AtmelDevice dev) { super(dev, 24, 24); }
+    }
+
+    public Sector sector(int col, int row) { return new Sector(col, row); }
+    public final class Sector {
+        public final int col;
+        public final int row;
+        public Sector(int col, int row) {
+            if (row % 4 != 0) throw new Error("Sector must be created with a multiple-of-4 row");
+            if (col % 4 != 0) throw new Error("Sector must be created with a multiple-of-4 col");
+            this.row = row;
+            this.col = col;
+        }
+    }
+
+    public Cell cell(int col, int row) { return new Cell(col, row); }
+    public final class Cell {
+        public final int col;
+        public final int row;
+        public Sector getSector() { return sector(col - (col % 4), row - (row % 4)); }
+        public Cell(int col, int row) {
+            this.row = row;
+            this.col = col;
+        }
+
+        /* bit positions mean:  [MSB] ___ __y _x_ _xy z__ z_y zx_ zxy [LSB] */
+        public void ylut(byte table)   { dev.mode4(6, row, col, ~table); }
+
+        /* bit positions mean:  [MSB] ___ __y _x_ _xy z__ z_y zx_ zxy [LSB] */
+        public void xlut(byte table)   { dev.mode4(7, row, col, ~table); }
+
+        public void ff_reset_value(boolean value) {
+            //dev.mode4( /* FIXME WRONG!!! */, row, col, 3, !value); return;
+        }
+
+        public void out(int plane, boolean enable) {
+            switch(plane) {
+                case 0: dev.mode4(0x00, row, col, 2, enable); return;
+                case 1: dev.mode4(0x00, row, col, 3, enable); return;
+                case 2: dev.mode4(0x00, row, col, 5, enable); return;
+                case 3: dev.mode4(0x00, row, col, 4, enable); return;
+                case 4: dev.mode4(0x00, row, col, 1, enable); return;
+                default: throw new RuntimeException("invalid argument");
+            }
+        }
+
+        public void h(int plane, boolean enable) {
+            switch(plane) {
+                case 0: dev.mode4(0x08, row, col, 0, enable); return;
+                case 1: dev.mode4(0x08, row, col, 2, enable); return;
+                case 2: dev.mode4(0x08, row, col, 5, enable); return;
+                case 3: dev.mode4(0x08, row, col, 6, enable); return;
+                case 4: dev.mode4(0x00, row, col, 6, enable); return;
+                default: throw new RuntimeException("invalid argument");
+            }
+        }
+        
+        public void v(int plane, boolean enable) {
+            switch(plane) {
+                case 0: dev.mode4(0x08, row, col, 1, enable); return;
+                case 1: dev.mode4(0x08, row, col, 3, enable); return;
+                case 2: dev.mode4(0x08, row, col, 4, enable); return;
+                case 3: dev.mode4(0x08, row, col, 7, enable); return;
+                case 4: dev.mode4(0x00, row, col, 7, enable); return;
+                default: throw new RuntimeException("invalid argument");
+            }
+        }
+        
+        public void t(boolean z, boolean w, boolean fb) {
+            // still not totally satisfied...
+            //     how to we distinguish between z&w vs z or w&fb vs fb?
+            //     what does it mean for both bits (0x30) to be set to 1?
+            if (fb && z) throw new RuntimeException("invalid combination");
+            int result = 0;
+            if (z)  result |= 0x20;
+            if (fb) result |= 0x10;
+            dev.mode4(1, row, col, result, 0x30);
+        }
+
+        public void c(int source) {
+            switch(source) {
+                case XLUT: dev.mode4(1, row, col, 0x00, 0xc0); break;
+                case YLUT: dev.mode4(1, row, col, 0x40, 0xc0); break;
+                case ZMUX: dev.mode4(1, row, col, 0x80, 0xc0); break;
+                default:   throw new RuntimeException("Invalid Argument");
+            }
+        }
+
+        public void b(boolean registered) { dev.mode4(1, row, col, 3, !registered); }
+        public void f(boolean registered) { dev.mode4(1, row, col, 2, !registered); }
+
+        public void xo(boolean center)    { dev.mode4(1, row, col, 1, center); }
+        public void yo(boolean center)    { dev.mode4(1, row, col, 0, center); }
+
+        public void oe(int source) {
+            switch(source) {
+                case NONE: dev.mode4(0x02, row, col, 0, 0x3); break;
+                case H4:   dev.mode4(0x02, row, col, 1, 0x3); break;
+                case V4:   dev.mode4(0x02, row, col, 2, 0x3); break;
+                default: throw new RuntimeException("invalid argument");
+            }
+        }
+
+        public void xin(int source) {
+            switch(source) {
+                case SW: dev.mode4(0x03, row, col, 4, false); dev.mode4(0x05, row, col, 1<<7); break;
+                case NE: dev.mode4(0x03, row, col, 4, false); dev.mode4(0x05, row, col, 1<<6); break;
+                case SE: dev.mode4(0x03, row, col, 4, false); dev.mode4(0x05, row, col, 1<<5); break;
+                case NW: dev.mode4(0x03, row, col, 4, false); dev.mode4(0x05, row, col, 1<<4); break;
+                case L4: dev.mode4(0x03, row, col, 4, true);  dev.mode4(0x05, row, col,    0); break;
+                case L3: dev.mode4(0x03, row, col, 4, false); dev.mode4(0x05, row, col, 1<<3); break;
+                case L2: dev.mode4(0x03, row, col, 4, false); dev.mode4(0x05, row, col, 1<<2); break;
+                case L1: dev.mode4(0x03, row, col, 4, false); dev.mode4(0x05, row, col, 1<<1); break;
+                case L0: dev.mode4(0x03, row, col, 4, false); dev.mode4(0x05, row, col, 1<<0); break;
+                default: throw new RuntimeException("invalid argument");
+            }
+        }
+
+        // FIXME: cancel out the others
+        public void yin(int source) {
+            switch(source) {
+                case NORTH: dev.mode4(0x02, row, col, 6, false); dev.mode4(0x04, row, col, 1<<7); break;
+                case SOUTH: dev.mode4(0x02, row, col, 6, false); dev.mode4(0x04, row, col, 1<<6); break;
+                case WEST:  dev.mode4(0x02, row, col, 6, false); dev.mode4(0x04, row, col, 1<<5); break;
+                case EAST:  dev.mode4(0x02, row, col, 6, false); dev.mode4(0x04, row, col, 1<<4); break;
+                case L4:    dev.mode4(0x02, row, col, 6, true);  dev.mode4(0x04, row, col,    0); break;
+                case L3:    dev.mode4(0x02, row, col, 6, false); dev.mode4(0x04, row, col, 1<<3); break;
+                case L2:    dev.mode4(0x02, row, col, 6, false); dev.mode4(0x04, row, col, 1<<2); break;
+                case L1:    dev.mode4(0x02, row, col, 6, false); dev.mode4(0x04, row, col, 1<<1); break;
+                case L0:    dev.mode4(0x02, row, col, 6, false); dev.mode4(0x04, row, col, 1<<0); break;
+                default: throw new RuntimeException("invalid argument");
+            }
+        }
+
+        public void win(int source) {
+            switch(source) {
+                case L4:    dev.mode4(0x03, row, col, 1<<5, 0xEC); break;
+                case L3:    dev.mode4(0x03, row, col, 1<<6, 0xEC); break;
+                case L2:    dev.mode4(0x03, row, col, 1<<7, 0xEC); break;
+                case L1:    dev.mode4(0x03, row, col, 1<<3, 0xEC); break;
+                case L0:    dev.mode4(0x03, row, col, 1<<2, 0xEC); break;
+                default: throw new RuntimeException("invalid argument");
+            }
+        }
+
+        public void zin(int source) {
+            switch(source) {
+                case L4:    dev.mode4(0x02, row, col, 1<<7, 0xDB); break;
+                case L3:    dev.mode4(0x02, row, col, 1<<5, 0xDB); break;
+                case L2:    dev.mode4(0x02, row, col, 1<<4, 0xDB); break;
+                case L1:    dev.mode4(0x02, row, col, 1<<3, 0xDB); break;
+                case L0:    dev.mode4(0x02, row, col, 1<<2, 0xDB); break;
+                default: throw new RuntimeException("invalid argument");
+            }
+        }
+
+    }
+
+    public IOB iob_top(int col, boolean primary)   { return new IOB(col, 0, primary); }
+    public IOB iob_bot(int col, boolean primary)   { return new IOB(col, 1, primary); }
+    public IOB iob_left(int row, boolean primary)  { return new IOB(1, row, primary); }
+    public IOB iob_right(int row, boolean primary) { return new IOB(2, row, primary); }
+    /*
+    public IOB fromPin(int pin) {
+        if (pin >=  4 && pin <= 11) return io(pin-3);
+        if (pin >= 15 && pin <= 18) return io(pin-2);
+        if (pin >= 19 && pin <= 24) return io(pin);
+        if (pin >= 27 && pin <= 30) return io(pin-2);
+        if (pin >= 33 && pin <= 36) return io(pin);
+        if (pin >= 38 && pin <= 47) return io(pin+1);
+
+
+        if (pin >= 33 && pin <= 36) return io(pin+36);
+        if (pin >= 38 && pin <= 41) return io(pin+43);
+        if (pin >= 42 && pin <= 43) return io(pin+47);
+        if (pin >= 44 && pin <= 47) return io(pin+49);
+        if (pin >= 57 && pin <= 62) return io(pin+40);
+        if (pin >= 63 && pin <= 66) return io(pin+46);
+        if (pin >= 68 && pin <= 71) return io(pin+53);
+        if (pin >= 72 && pin <= 73) return io(pin+53);
+        if (pin >= 74 && pin <= 75) return io(pin+63);
+        if (pin >= 76 && pin <= 77) return io(143+(pin-76));
+        if (pin >= 80 && pin <= 81) return io(145+(pin-80));
+        if (pin >= 82 && pin <= 85) return io(151+(pin-82));
+        if (pin >= 86 && pin <= 89) return io(165+(pin-86));
+        if (pin >= 91 && pin <= 94) return io(177+(pin-91));
+        if (pin >= 95 && pin <= 96) return io(183+(pin-95));
+        if (pin >= 97 && pin <= 100) return io(189+(pin-97));
+        if (pin >= 161 && pin <= 164) return io(289+(pin-161));
+        if (pin >= 165 && pin <= 166) return io(297+(pin-165));
+        if (pin >= 167 && pin <= 168) return io(303+(pin-167));
+        if (pin >= 169 && pin <= 170) return io(309+(pin-169));
+        if (pin >= 172 && pin <= 173) return io(313+(pin-172));
+        if (pin >= 174 && pin <= 175) return io(325+(pin-174));
+        if (pin >= 176 && pin <= 179) return io(327+(pin-176));
+        if (pin >= 180 && pin <= 181) return io(335+(pin-180));
+        if (pin >= 184 && pin <= 185) return io(337+(pin-184));
+        if (pin >= 186 && pin <= 191) return io(343+(pin-186));
+        if (pin >= 192 && pin <= 193) return io(359+(pin-192));
+        if (pin >= 195 && pin <= 196) return io(363+(pin-195));
+        if (pin >= 197 && pin <= 200) return io(369+(pin-197));
+        if (pin >= 201 && pin <= 204) return io(381+(pin-201));
+    }
+    public io(int ionum) {
+        if (ionum <= 94) {
+            int cell = (94 - pin) / 2;
+            boolean primary = cell * 2 == (94-pin);
+        }
+    }
+    */
+    public final class IOB {
+        public final int col;
+        public final int row;
+        public final boolean primary;
+        public IOB(int col, int row, boolean primary) { this.col = col; this.row = row; this.primary = primary; }
+
+        private int z(int code) { return 0x60 | (primary ? 0x08 : 0x10) | code; }
+        public void pullup()   { dev.mode4(z(0), row, col, (dev.mode4(z(0), row, col) & (~0x6)) | 0x00); }
+        public void pulldown() { dev.mode4(z(0), row, col, (dev.mode4(z(0), row, col) & (~0x6)) | 0x03); }
+        public void pullnone() { dev.mode4(z(0), row, col, (dev.mode4(z(0), row, col) & (~0x6)) | 0x01); }
+        public void oe(boolean oe) {
+            int old =  dev.mode4(z(1), row, col) & (~(1<<5));
+            old     |= oe ? 0 : (1<<5);
+            dev.mode4(z(1), row, col, old & 0xff);
+        }
+        public void output(int which) {
+            if (which < 0 || which > 6) throw new RuntimeException("oem(x) only valid for 0<=x<=5");
+            int d = dev.mode4(z(1), row, col) & 0x80;
+            if (which>0) { d |= 1 << (which==6 ? 6 : which==0 ? 5 : (which-1)); }
+            Log.warn("z", Integer.toString(z(1),16));
+            Log.warn("y", Integer.toString(row,16));
+            Log.warn("x", Integer.toString(col,16));
+            Log.warn("d", Integer.toString(d,16));
+            dev.mode4(z(1), row, col, d);
+        }
+        
+    }
+
+}
index 07be997..484d76f 100644 (file)
@@ -6,8 +6,47 @@ import java.util.*;
 
 public abstract class AtmelDevice extends Bits implements Device {
 
+    public static class Constants {
+        public static final int NONE  = -1;
+        public static final int L0    = 0;
+        public static final int L1    = 1;
+        public static final int L2    = 2;
+        public static final int L3    = 3;
+        public static final int L4    = 4;
+
+        public static final int NORTH = 8;
+        public static final int SOUTH = 9;
+        public static final int EAST  = 10;
+        public static final int WEST  = 11;
+
+        public static final int XLUT  = 12;
+        public static final int YLUT  = 13;
+        public static final int ZMUX  = 14;
+
+        public static final int H4    = 15;
+        public static final int V4    = 16;
+
+        public static final int NW    = 20;
+        public static final int SW    = 21;
+        public static final int NE    = 22;
+        public static final int SE    = 23;
+    }
+
     /** issue a command to the device in Mode4 format; see Gosset's documentation for further details */
     public abstract void mode4(int z, int y, int x, int d) throws DeviceException;
+    public abstract byte mode4(int z, int y, int x);
+    public          void mode4(int z, int y, int x, int d, int invmask) {
+        int old = mode4(z, y, x);
+        old &= ~invmask;
+        old |= d;
+        mode4(z, y, x, old);
+    }
+    public          void mode4(int z, int y, int x, int bit, boolean set) {
+        int old = mode4(z, y, x);
+        old &= 1 << bit;
+        old |= set ? (1 << bit) : 0;
+        mode4(z, y, x, old);
+    }
     /*
     public Sector sector(int col, int row) { return new Sector(col, row); }
     public final class Sector {
index 9e06fd1..f00f794 100644 (file)
@@ -48,6 +48,12 @@ public class AvrDrone extends AtmelDevice {
         } catch (InterruptedException e) { throw new DeviceException(e); }
     }
 
+    private byte[][][] cache = new byte[24][][];
+    public byte mode4(int z, int y, int x) throws DeviceException {
+        if (cache[x]==null) return 0;
+        if (cache[x][y]==null) return 0;
+        return cache[x][y][z];
+    }
     public void mode4(int z, int y, int x, int d) throws DeviceException {
         try {
             Log.debug(this, "writing configuration frame [zyxd]: " +
@@ -61,6 +67,9 @@ public class AvrDrone extends AtmelDevice {
             out.writeByte(y);
             out.writeByte(x);
             out.writeByte(d);
+            if (cache[x & 0xff]==null) cache[x & 0xff] = new byte[24][];
+            if (cache[x & 0xff][y & 0xff]==null) cache[x & 0xff][y & 0xff] = new byte[256];
+            cache[x & 0xff][y & 0xff][z & 0xff] = (byte)(d & 0xff);
         } catch (IOException e) { throw new DeviceException(e); }
     }