checkpoint
[slipway.git] / src / com / atmel / fpslic / FpslicRaw.java
1 package com.atmel.fpslic;
2
3 import com.ftdi.usb.*;
4 import java.io.*;
5
6 /**
7  * "Raw" access to an <i>unconfigured</i> FPSLIC -- used to load the initial bitstream.
8  */
9 public class FpslicRaw {
10
11     private FpslicPins pins;
12
13     public FpslicRaw(FpslicPins pins) throws IOException {
14         this.pins = pins;
15         reset();
16     }
17
18     public void reset() throws IOException {
19
20         pins.avrrstPin(false);
21         pins.configDataPin(false);
22         pins.resetPin(false);
23         pins.cclkPin(false);
24         
25         pins.conPin(false);
26         pins.flush();
27
28         pins.resetPin(false);
29         try { Thread.sleep(500); } catch (Exception e) { }
30         if (pins.initPin()) throw new RuntimeException("INIT was still high after pulling RESET low");
31
32         pins.resetPin(true);
33         try { Thread.sleep(500); } catch (Exception e) { }
34         if (!pins.initPin()) throw new RuntimeException("INIT was still low after releasing RESET");
35
36         sendConfigBits(0,2);
37         pins.flush();
38     }
39
40     public OutputStream getConfigStream() throws IOException {
41         reset();
42         return new OutputStream() {
43                 int bytes = 0;
44                 int bits = 0;
45                 public void write(int in) throws IOException {
46                     for(int i=7; i>=0; i--) {
47                         bits++;
48                         sendConfigBits((((in & 0xff) & (1<<i))!=0)?1:0, 1);
49                     }
50                 }
51                 public void write(byte[] b, int off, int len) throws IOException {
52                     for(int i=off; i<off+len; i++)
53                         write(b[i]);
54                 }
55                 public void flush() throws IOException {
56                     pins.flush();
57                 }
58                 public void close() throws IOException {
59
60                     pins.flush();
61
62                     // turn off the CON pin we've been pulling low...
63                     pins.releaseConPin();
64
65                     if (!pins.initPin())
66                         throw new RuntimeException("initialization failed at " + bytes);
67                     for(int i=0; i<100; i++) {
68                         pins.flush();
69                         if (!pins.initPin())
70                             throw new RuntimeException("initialization failed at " + bytes);
71                         try { Thread.sleep(20); } catch (Exception e) { }
72                         sendConfigBits(0,1);
73                     }
74
75                     pins.close();
76                 }
77             };
78     }
79
80     public OutputStream getOutputStream() throws IOException { return pins.getUartOutputStream(); }
81     public InputStream  getInputStream() throws IOException { return pins.getUartInputStream(); }
82
83     public void selfTest() throws Exception {
84         boolean pin;
85         System.out.print("smoke check: ");
86
87         // correct preamble
88         getConfigStream();
89         sendConfigBits(Integer.parseInt("00000000", 2), 8);
90         sendConfigBits(Integer.parseInt("10110111", 2), 8);
91         sendConfigBits(0,1);
92         pins.flush();
93         try { Thread.sleep(100); } catch (Exception e) { }
94         pin = pins.initPin();
95         System.out.print((pin ? green(" [pass]") : red(" [FAIL]")));
96
97         // preamble shifted one bit earlier than it should be
98         getConfigStream();
99         sendConfigBits(Integer.parseInt("0000000",  2), 7);
100         sendConfigBits(Integer.parseInt("10110111", 2), 8);
101         sendConfigBits(0, 2);
102         pins.flush();
103         try { Thread.sleep(100); } catch (Exception e) { }
104         pin = pins.initPin();
105         System.out.print((pin ? red(" [FAIL]") : green(" [pass]")));
106
107         // preamble shifted one bit later than it should be
108         getConfigStream();
109         sendConfigBits(Integer.parseInt("000000000", 2), 9);
110         sendConfigBits(Integer.parseInt("10110111",  2), 8);
111         //sendConfigBits(0, 1);
112         pins.flush();
113         try { Thread.sleep(100); } catch (Exception e) { }
114         pin = pins.initPin();
115         System.out.print((pin ? red(" [FAIL]") : green(" [pass]")));
116
117         // plain 'ol bogus preamble
118         getConfigStream();
119         sendConfigBits(Integer.parseInt("00000000", 2), 8);
120         sendConfigBits(Integer.parseInt("11110111", 2), 8);
121         sendConfigBits(0, 1);
122         pins.flush();
123         try { Thread.sleep(100); } catch (Exception e) { }
124         pin = pins.initPin();
125         System.out.print((pin ? red(" [FAIL]") : green(" [pass]")));
126
127         System.out.println();
128     }
129
130     // Private //////////////////////////////////////////////////////////////////////////////
131
132     private void sendConfigBits(int dat, int numbits) throws IOException {
133         for(int i=(numbits-1); i>=0; i--) {
134             boolean bit = (dat & (1<<i)) != 0;
135             pins.configDataPin(bit);
136             pins.cclkPin(true);
137             pins.cclkPin(false);
138             //dbits &= ~(1<<6);  // let the clock fall with the next data bit, whenever it goes out
139         }
140     }
141
142     private static String red(Object o) { return "\033[31m"+o+"\033[0m"; }
143     private static String green(Object o) { return "\033[32m"+o+"\033[0m"; }
144
145 }