Peek range for Chipcon IRAM.
[goodfet] / client / GoodFET.py
1 #!/usr/bin/env python
2 # GoodFET Client Library
3
4 # (C) 2009 Travis Goodspeed <travis at radiantmachines.com>
5 #
6 # This code is being rewritten and refactored.  You've been warned!
7
8 import sys, time, string, cStringIO, struct, glob, serial, os;
9
10
11 class GoodFET:
12     """GoodFET Client Library"""
13     def __init__(self, *args, **kargs):
14         self.data=[0];
15     def timeout(self):
16         print "timeout\n";
17     def serInit(self, port=None):
18         """Open the serial port"""
19         
20         if port is None and os.environ.get("GOODFET")!=None:
21             glob_list = glob.glob(os.environ.get("GOODFET"));
22             if len(glob_list) > 0:
23                 port = glob_list[0];
24         if port is None:
25             glob_list = glob.glob("/dev/tty.usbserial*");
26             if len(glob_list) > 0:
27                 port = glob_list[0];
28         if port is None:
29             glob_list = glob.glob("/dev/ttyUSB*");
30             if len(glob_list) > 0:
31                 port = glob_list[0];
32         
33         self.serialport = serial.Serial(
34             port,
35             #9600,
36             115200,
37             parity = serial.PARITY_NONE
38             )
39         
40         #Explicitly set RTS
41         self.serialport.setRTS(1);
42         #Drop DTR, which is !RST, low to begin the app.
43         self.serialport.setDTR(0);
44         self.serialport.flushInput()
45         self.serialport.flushOutput()
46         
47         #Read and handle the initial command.
48         #time.sleep(1);
49         self.readcmd(); #Read the first command.
50         if(self.verb!=0x7F):
51             print "Verb %02x is wrong.  Incorrect firmware?" % self.verb;
52         #print "Connected."
53     def getbuffer(self,size=0x1c00):
54         writecmd(0,0xC2,[size&0xFF,(size>>16)&0xFF]);
55         print "Got %02x%02x buffer size." % (self.data[1],self.data[0]);
56     def writecmd(self, app, verb, count=0, data=[]):
57         """Write a command and some data to the GoodFET."""
58         self.serialport.write(chr(app));
59         self.serialport.write(chr(verb));
60         
61         
62         #print "TX %02x %02x" % (app,verb);
63         
64         #little endian 16-bit length
65         self.serialport.write(chr(count&0xFF));
66         self.serialport.write(chr(count>>8));
67         
68         #print "count=%02x, len(data)=%04x" % (count,len(data));
69         
70         if count!=0:
71             for i in range(0,count):
72                 #print "Converting %02x at %i" % (data[i],i)
73                 data[i]=chr(data[i]);
74             outstr=''.join(data);
75             self.serialport.write(outstr);
76         if not self.besilent:
77             self.readcmd();
78         
79     besilent=0;
80     app=0;
81     verb=0;
82     count=0;
83     data="";
84
85     def readcmd(self):
86         """Read a reply from the GoodFET."""
87         while 1:
88             #print "Reading...";
89             self.app=ord(self.serialport.read(1));
90             #print "APP=%2x" % self.app;
91             self.verb=ord(self.serialport.read(1));
92             #print "VERB=%02x" % self.verb;
93             self.count=(
94                 ord(self.serialport.read(1))
95                 +(ord(self.serialport.read(1))<<8)
96                 );
97             
98             #Debugging string; print, but wait.
99             if self.app==0xFF and self.verb==0xFF:
100                 print "DEBUG %s" % self.serialport.read(self.count);
101             else:
102                 self.data=self.serialport.read(self.count);
103                 return self.data;
104     
105     #Monitor stuff
106     def silent(self,s=0):
107         """Transmissions halted when 1."""
108         self.besilent=s;
109         print "besilent is %i" % self.besilent;
110         self.writecmd(0,0xB0,1,[s]);
111         
112     def out(self,byte):
113         """Write a byte to P5OUT."""
114         self.writecmd(0,0xA1,1,[byte]);
115     def dir(self,byte):
116         """Write a byte to P5DIR."""
117         self.writecmd(0,0xA0,1,[byte]);
118     def peekbyte(self,address):
119         """Read a byte of memory from the monitor."""
120         self.data=[address&0xff,address>>8];
121         self.writecmd(0,0x02,2,self.data);
122         #self.readcmd();
123         return ord(self.data[0]);
124     def peekword(self,address):
125         """Read a word of memory from the monitor."""
126         return self.peekbyte(address)+(self.peekbyte(address+1)<<8);
127     def pokebyte(self,address,value):
128         """Set a byte of memory by the monitor."""
129         self.data=[address&0xff,address>>8,value];
130         self.writecmd(0,0x03,3,self.data);
131         return ord(self.data[0]);
132     def dumpmem(self,begin,end):
133         i=begin;
134         while i<end:
135             print "%04x %04x" % (i, self.peekword(i));
136             i+=2;
137     def monitor_ram_pattern(self):
138         """Overwrite all of RAM with 0xBEEF."""
139         self.writecmd(0,0x90,0,self.data);
140         return;
141     def monitor_ram_depth(self):
142         """Determine how many bytes of RAM are unused by looking for 0xBEEF.."""
143         self.writecmd(0,0x91,0,self.data);
144         return ord(self.data[0])+(ord(self.data[1])<<8);
145     
146     #Baud rates.
147     baudrates=[115200, 
148                9600,
149                19200,
150                38400,
151                57600,
152                115200];
153     def setBaud(self,baud):
154         """Change the baud rate.  TODO fix this."""
155         rates=self.baudrates;
156         self.data=[baud];
157         print "Changing FET baud."
158         self.serialport.write(chr(0x00));
159         self.serialport.write(chr(0x80));
160         self.serialport.write(chr(1));
161         self.serialport.write(chr(baud));
162         
163         print "Changed host baud."
164         self.serialport.setBaudrate(rates[baud]);
165         time.sleep(1);
166         self.serialport.flushInput()
167         self.serialport.flushOutput()
168         
169         print "Baud is now %i." % rates[baud];
170         return;
171     def readbyte(self):
172         return ord(self.serialport.read(1));
173     def findbaud(self):
174         for r in self.baudrates:
175             print "\nTrying %i" % r;
176             self.serialport.setBaudrate(r);
177             #time.sleep(1);
178             self.serialport.flushInput()
179             self.serialport.flushOutput()
180             
181             for i in range(1,10):
182                 self.readbyte();
183             
184             print "Read %02x %02x %02x %02x" % (
185                 self.readbyte(),self.readbyte(),self.readbyte(),self.readbyte());
186     def monitortest(self):
187         """Self-test several functions through the monitor."""
188         print "Performing monitor self-test.";
189         
190         if self.peekword(0x0c00)!=0x0c04 and self.peekword(0x0c00)!=0x0c06:
191             print "ERROR Fetched wrong value from 0x0c04.";
192         self.pokebyte(0x0021,0); #Drop LED
193         if self.peekbyte(0x0021)!=0:
194             print "ERROR, P1OUT not cleared.";
195         self.pokebyte(0x0021,1); #Light LED
196         
197         print "Self-test complete.";
198     
199     
200
201     def I2Csetup(self):
202         """Move the FET into the I2C application."""
203         self.writecmd(0x02,0x10,0,self.data); #SPI/SETUP
204     def I2Cstart(self):
205         """Start an I2C transaction."""
206         self.writecmd(0x02,0x20,0,self.data); #SPI/SETUP
207     def I2Cstop(self):
208         """Stop an I2C transaction."""
209         self.writecmd(0x02,0x21,0,self.data); #SPI/SETUP
210     def I2Cread(self,len=1):
211         """Read len bytes by I2C."""
212         self.writecmd(0x02,0x00,1,[len]); #SPI/SETUP
213         return self.data;
214     def I2Cwrite(self,bytes):
215         """Write bytes by I2C."""
216         self.writecmd(0x02,0x01,len(bytes),bytes); #SPI/SETUP
217         return ord(self.data[0]);