From f4da556e7246275d49adf8bb7b4c5b0192bc7b87 Mon Sep 17 00:00:00 2001 From: adam Date: Thu, 9 Mar 2006 14:21:32 +0100 Subject: [PATCH] got all intra-CLB switches coded up, but untested --- Makefile | 7 +- src/edu/berkeley/obits/AtmelSerial.java | 67 ++++- src/edu/berkeley/obits/Device.java | 2 +- src/edu/berkeley/obits/device/atmel/At40k.java | 257 ++++++++++++++++++++ .../berkeley/obits/device/atmel/AtmelDevice.java | 39 +++ src/edu/berkeley/obits/device/atmel/AvrDrone.java | 9 + 6 files changed, 376 insertions(+), 5 deletions(-) create mode 100644 src/edu/berkeley/obits/device/atmel/AT94k.java create mode 100644 src/edu/berkeley/obits/device/atmel/At40k.java diff --git a/Makefile b/Makefile index 8ab4dc2..bc729bc 100644 --- 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! diff --git a/src/edu/berkeley/obits/AtmelSerial.java b/src/edu/berkeley/obits/AtmelSerial.java index 2a9f352..a7a4dec 100644 --- a/src/edu/berkeley/obits/AtmelSerial.java +++ b/src/edu/berkeley/obits/AtmelSerial.java @@ -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(); } } diff --git a/src/edu/berkeley/obits/Device.java b/src/edu/berkeley/obits/Device.java index b56114b..a6074ac 100644 --- a/src/edu/berkeley/obits/Device.java +++ b/src/edu/berkeley/obits/Device.java @@ -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 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 index 0000000..3d43d75 --- /dev/null +++ b/src/edu/berkeley/obits/device/atmel/At40k.java @@ -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); + } + + } + +} diff --git a/src/edu/berkeley/obits/device/atmel/AtmelDevice.java b/src/edu/berkeley/obits/device/atmel/AtmelDevice.java index 07be997..484d76f 100644 --- a/src/edu/berkeley/obits/device/atmel/AtmelDevice.java +++ b/src/edu/berkeley/obits/device/atmel/AtmelDevice.java @@ -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 { diff --git a/src/edu/berkeley/obits/device/atmel/AvrDrone.java b/src/edu/berkeley/obits/device/atmel/AvrDrone.java index 9e06fd1..f00f794 100644 --- a/src/edu/berkeley/obits/device/atmel/AvrDrone.java +++ b/src/edu/berkeley/obits/device/atmel/AvrDrone.java @@ -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); } } -- 1.7.10.4