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