f48001736214a5efb77e88dcd8cd49d6cbd96abb
[goodfet] / client / GoodFETAVR.py
1 #!/usr/bin/env python
2 # GoodFET SPI and SPIFlash 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 from GoodFET import GoodFET;
11
12 class GoodFETAVR(GoodFET):
13     AVRAPP=0x32;
14     APP=AVRAPP;
15     AVRVendors={0x1E: "Atmel",
16                 0x00: "Locked",
17                 };
18     
19     #List from avr910.asm and other sources.
20     #More devices at http://avr.fenceline.de/device_data.html
21     AVRDevices={
22         0x9003: "tiny10",
23         0x9004: "tiny11",
24         0x9005: "tiny12",
25         0x9006: "tiny15",
26         0x9007: "tiny13",
27         0x9108: "tiny25",
28         0x930B: "tiny85",
29         0x9206: "tiny45",
30         
31         0x9001: "S1200",
32         
33         0x9101: "S1213",
34         0x9102: "S2323",
35         0x9105: "S2333",
36         0x9103: "S2343",
37         
38         0x9201: "S4414",
39         0x9203: "S4433",
40         0x9202: "S4434",
41         
42         0x9301: "S8515",
43         0x9303: "S8535",
44         
45         0x9305: "mega83",
46         0x930a: "mega88",
47         0x9701: "mega103",
48         0x9401: "mega161",
49         0x9402: "mega163",
50         0x9406: "mega168",
51         
52         0x950f: "mega328",
53         0x950d: "mega325",
54         0x9508: "mega32"
55         };
56     
57     def setup(self):
58         """Move the FET into the AVR application."""
59         self.writecmd(self.AVRAPP,0x10,0,self.data); #SPI/SETUP
60     
61     def trans(self,data):
62         """Exchange data by AVR.
63         Input should probably be 4 bytes."""
64         self.data=data;
65         self.writecmd(self.AVRAPP,0x00,len(data),data);
66         return self.data;
67
68     def start(self):
69         """Start the connection."""
70         self.writecmd(self.AVRAPP,0x20,0,None);
71     def forcestart(self):
72         """Forcibly start a connection."""
73         
74         for i in range(0x880,0xfff):
75             #self.glitchVoltages(0x880, i);
76             self.start();
77             bits=self.lockbits();
78             print "At %04x, Lockbits: %02x" % (i,bits);
79             if(bits==0xFF): return;
80     def erase(self):
81         """Erase the target chip."""
82         self.writecmd(self.AVRAPP,0xF0,0,None);
83     def lockbits(self):
84         """Read the target's lockbits."""
85         self.writecmd(self.AVRAPP,0x82,0,None);
86         return ord(self.data[0]);
87     def setlockbits(self,bits=0x00):
88         """Read the target's lockbits."""
89         self.writecmd(self.AVRAPP,0x92,1,[bits]);
90         return self.lockbits();
91     
92     def eeprompeek(self, adr):
93         """Read a byte of the target's EEPROM."""
94         self.writecmd(self.AVRAPP,0x81 ,2,
95                       [ (adr&0xFF), (adr>>8)]
96                       );#little-endian address
97         return ord(self.data[0]);
98     def flashpeek(self, adr):
99         """Read a byte of the target's EEPROM."""
100         self.writecmd(self.AVRAPP,0x02 ,2,
101                       [ (adr&0xFF), (adr>>8)]
102                       );#little-endian address
103         return ord(self.data[0]);
104     def flashpeekblock(self, adr):
105         """Read a byte of the target's EEPROM."""
106         self.writecmd(self.AVRAPP,0x02 ,4,
107                       [ (adr&0xFF), (adr>>8) &0xFF, 0x80, 0x00]
108                       );
109         return self.data;
110     
111     def eeprompoke(self, adr, val):
112         """Write a byte of the target's EEPROM."""
113         self.writecmd(self.AVRAPP,0x91 ,3,
114                       [ (adr&0xFF), (adr>>8), val]
115                       );#little-endian address
116         return ord(self.data[0]);
117     
118     def identstr(self):
119         """Return an identifying string."""
120         self.writecmd(self.AVRAPP,0x83,0, None);
121         vendor=self.AVRVendors.get(ord(self.data[0]));
122         deviceid=(ord(self.data[1])<<8)+ord(self.data[2]);
123         device=self.AVRDevices.get(deviceid);
124         
125         #Return hex if device is unknown.
126         #They are similar enough that it needn't be known.
127         if device==None:
128             device=("0x%04x" % deviceid);
129         
130         return "%s %s" % (vendor,device);