96e8ad6d16bb1a6249b6ead58e4ecd7f44c646f0
[goodfet] / client / GoodFETMAXUSB.py
1 #!/usr/bin/env python
2 # GoodFET Client Library for Maxim USB Chips.
3
4 # (C) 2012 Travis Goodspeed <travis at radiantmachines.com>
5 #
6 # This code is being rewritten and refactored.  You've been warned!
7
8
9 import sys, time, string, cStringIO, struct, glob, os;
10
11 from GoodFET import GoodFET;
12
13 #Handy registers.
14 rEP0FIFO=0
15 rEP1OUTFIFO=1
16 rEP2INFIFO=2
17 rEP3INFIFO=3
18 rSUDFIFO=4
19 rEP0BC=5
20 rEP1OUTBC=6
21 rEP2INBC=7
22 rEP3INBC=8
23 rEPSTALLS=9
24 rCLRTOGS=10
25 rEPIRQ=11
26 rEPIEN=12
27 rUSBIRQ=13
28 rUSBIEN=14
29 rUSBCTL=15
30 rCPUCTL=16
31 rPINCTL=17
32 rREVISION=18
33 rFNADDR=19
34 rIOPINS=20
35
36 # R11 EPIRQ register bits
37 bmSUDAVIRQ =0x20
38 bmIN3BAVIRQ =0x10
39 bmIN2BAVIRQ =0x08
40 bmOUT1DAVIRQ= 0x04
41 bmOUT0DAVIRQ= 0x02
42 bmIN0BAVIRQ =0x01
43
44 # R12 EPIEN register bits
45 bmSUDAVIE   =0x20
46 bmIN3BAVIE  =0x10
47 bmIN2BAVIE  =0x08
48 bmOUT1DAVIE =0x04
49 bmOUT0DAVIE =0x02
50 bmIN0BAVIE  =0x01
51
52
53 # ************************
54 # Standard USB Requests
55 SR_GET_STATUS           =0x00   # Get Status
56 SR_CLEAR_FEATURE        =0x01   # Clear Feature
57 SR_RESERVED             =0x02   # Reserved
58 SR_SET_FEATURE          =0x03   # Set Feature
59 SR_SET_ADDRESS          =0x05   # Set Address
60 SR_GET_DESCRIPTOR       =0x06   # Get Descriptor
61 SR_SET_DESCRIPTOR       =0x07   # Set Descriptor
62 SR_GET_CONFIGURATION    =0x08   # Get Configuration
63 SR_SET_CONFIGURATION    =0x09   # Set Configuration
64 SR_GET_INTERFACE        =0x0a   # Get Interface
65 SR_SET_INTERFACE        =0x0b   # Set Interface
66
67 # Get Descriptor codes  
68 GD_DEVICE               =0x01   # Get device descriptor: Device
69 GD_CONFIGURATION        =0x02   # Get device descriptor: Configuration
70 GD_STRING               =0x03   # Get device descriptor: String
71 GD_HID                  =0x21   # Get descriptor: HID
72 GD_REPORT               =0x22   # Get descriptor: Report
73
74 # SETUP packet offsets
75 bmRequestType           =0
76 bRequest                =1
77 wValueL                 =2
78 wValueH                 =3
79 wIndexL                 =4
80 wIndexH                 =5
81 wLengthL                =6
82 wLengthH                =7
83
84 # HID bRequest values
85 GET_REPORT              =1
86 GET_IDLE                =2
87 GET_PROTOCOL            =3
88 SET_REPORT              =9
89 SET_IDLE                =0x0A
90 SET_PROTOCOL            =0x0B
91 INPUT_REPORT            =1
92
93
94
95
96 class GoodFETMAXUSB(GoodFET):
97     MAXUSBAPP=0x40;
98     def MAXUSBsetup(self):
99         """Move the FET into the MAXUSB application."""
100         self.writecmd(self.MAXUSBAPP,0x10,0,self.data); #MAXUSB/SETUP
101         print "Connected to MAX342x Rev. %x" % (self.rreg(rREVISION));
102         self.wreg(rPINCTL,0x18); #Set duplex and negative INT level.
103         
104     def MAXUSBtrans8(self,byte):
105         """Read and write 8 bits by MAXUSB."""
106         data=self.MAXUSBtrans([byte]);
107         return ord(data[0]);
108     
109     def MAXUSBtrans(self,data):
110         """Exchange data by MAXUSB."""
111         self.data=data;
112         self.writecmd(self.MAXUSBAPP,0x00,len(data),data);
113         return self.data;
114
115     def rreg(self,reg):
116         """Peek 8 bits from a register."""
117         data=[reg<<3,0];
118         self.writecmd(self.MAXUSBAPP,0x00,len(data),data);
119         return ord(self.data[1]);
120     def rregAS(self,reg):
121         """Peek 8 bits from a register, setting AS."""
122         data=[(reg<<3)|1,0];
123         self.writecmd(self.MAXUSBAPP,0x00,len(data),data);
124         return ord(self.data[1]);
125     def wreg(self,reg,value):
126         """Poke 8 bits into a register."""
127         data=[(reg<<3)|2,value];
128         self.writecmd(self.MAXUSBAPP,0x00,len(data),data);        
129         return value;
130     def wregAS(self,reg,value):
131         """Poke 8 bits into a register, setting AS."""
132         data=[(reg<<3)|3,value];
133         self.writecmd(self.MAXUSBAPP,0x00,len(data),data);        
134         return value;
135     def readbytes(self,reg,length):
136         """Peek some bytes from a register."""
137         data=[(reg<<3)]+range(0,length);
138         self.writecmd(self.MAXUSBAPP,0x00,len(data),data);
139         toret=self.data[1:len(self.data)];
140         ashex="";
141         for foo in toret:
142             ashex=ashex+(" %02x"%ord(foo));
143         print "GET %02x==%s" % (reg,ashex);
144         return toret;
145     def writebytes(self,reg,tosend):
146         """Poke some bytes into a register."""
147         data="";
148         if type(tosend)==str:
149             data=chr((reg<<3)|2)+tosend;
150         else:
151             data=[(reg<<3)|2]+tosend;
152             ashex="";
153             for foo in tosend:
154                 ashex=ashex+(" %02x"%foo);
155             print "PUT %02x:=%s" % (reg,ashex)
156         self.writecmd(self.MAXUSBAPP,0x00,len(data),data);
157     def usb_connect(self):
158         """Connect the USB port."""
159         
160         #disconnect D+ pullup if host turns off VBUS
161         self.wreg(rUSBCTL,0x48);
162     def STALL_EP0(self):
163         """Stall for an unknown event."""
164         print "Stalling.";
165         self.wreg(rEPSTALLS,0x23); #All three stall bits.
166     def SETBIT(self,reg,val):
167         """Set a bit in a register."""
168         self.wreg(reg,self.rreg(reg)|val);
169 class GoodFETMAXUSBHID(GoodFETMAXUSB):
170     """This is an example HID keyboard driver, loosely based on the
171     MAX3420 examples."""
172     def hidinit(self):
173         """Initialize a USB HID device."""
174         self.usb_connect();
175         self.hidrun();
176         
177     def hidrun(self):
178         """Main loop of the USB HID emulator."""
179         print "Starting a HID device.  This won't return.";
180         while 1:
181             self.service_irqs();
182     def do_SETUP(self):
183         """Handle USB Enumeration"""
184         
185         #Grab the SETUP packet from the buffer.
186         SUD=self.readbytes(rSUDFIFO,8);
187         
188         #Parse the SETUP packet
189         print "Handling a setup packet type 0x%02x" % ord(SUD[bmRequestType]);
190         setuptype=(ord(SUD[bmRequestType])&0x60);
191         if setuptype==0x00:
192             self.std_request(SUD);
193         elif setuptype==0x20:
194             self.class_request(SUD);
195         elif setuptype==0x40:
196             self.vendor_request(SUD);
197         else:
198             print "Unknown request type 0x%02x." % ord(SUD[bmRequestType])
199             self.STALL_EP0();
200     def class_request(self,SUD):
201         """Handle a class request."""
202         print "Stalling a class request.";
203         self.STALL_EP0();
204     def vendor_request(self,SUD):
205         print "Stalling a vendor request.";
206         self.STALL_EP0();
207     def std_request(self,SUD):
208         """Handles a standard setup request."""
209         setuptype=ord(SUD[bRequest]);
210         if setuptype==SR_GET_DESCRIPTOR: self.send_descriptor(SUD);
211         elif setuptype==SR_SET_FEATURE: self.feature(1);
212         elif setuptype==SR_SET_CONFIGURATION: self.set_configuration(SUD);
213         elif setuptype==SR_GET_STATUS: self.get_status(SUD);
214         elif setuptype==SR_SET_ADDRESS: self.rregAS(rFNADDR);
215         elif setuptype==SR_GET_INTERFACE: self.get_interface(SUD);
216         else:
217             print "Stalling Unknown standard setup request type %02x" % setuptype;
218             
219             self.STALL_EP0();
220     
221     def get_interface(self,SUD):
222         """Handles a setup request for SR_GET_INTERFACE."""
223         if ord(SUD[wIndexL]==0):
224             self.wreg(rEP0FIFO,0);
225             self.wregAS(rEP0BC,1);
226         else:
227             self.STALL_EP0();
228     
229     #Device Descriptor
230     DD=[0x12,                   # bLength = 18d
231         0x01,                   # bDescriptorType = Device (1)
232         0x00,0x01,              # bcdUSB(L/H) USB spec rev (BCD)
233         0x00,0x00,0x00,         # bDeviceClass, bDeviceSubClass, bDeviceProtocol
234         0x40,                   # bMaxPacketSize0 EP0 is 64 bytes
235         0x6A,0x0B,              # idVendor(L/H)--Maxim is 0B6A
236         0x46,0x53,              # idProduct(L/H)--5346
237         0x34,0x12,              # bcdDevice--1234
238         1,2,3,                  # iManufacturer, iProduct, iSerialNumber
239         1];
240     #Configuration Descriptor
241     CD=[0x09,                   # bLength
242         0x02,                   # bDescriptorType = Config
243         0x22,0x00,              # wTotalLength(L/H) = 34 bytes
244         0x01,                   # bNumInterfaces
245         0x01,                   # bConfigValue
246         0x00,                   # iConfiguration
247         0xE0,                   # bmAttributes. b7=1 b6=self-powered b5=RWU supported
248         0x01,                   # MaxPower is 2 ma
249 # INTERFACE Descriptor
250         0x09,                   # length = 9
251         0x04,                   # type = IF
252         0x00,                   # IF #0
253         0x00,                   # bAlternate Setting
254         0x01,                   # bNum Endpoints
255         0x03,                   # bInterfaceClass = HID
256         0x00,0x00,              # bInterfaceSubClass, bInterfaceProtocol
257         0x00,                   # iInterface
258 # HID Descriptor--It's at CD[18]
259         0x09,                   # bLength
260         0x21,                   # bDescriptorType = HID
261         0x10,0x01,              # bcdHID(L/H) Rev 1.1
262         0x00,                   # bCountryCode (none)
263         0x01,                   # bNumDescriptors (one report descriptor)
264         0x22,                   # bDescriptorType       (report)
265         43,0,                   # CD[25]: wDescriptorLength(L/H) (report descriptor size is 43 bytes)
266 # Endpoint Descriptor
267         0x07,                   # bLength
268         0x05,                   # bDescriptorType (Endpoint)
269         0x83,                   # bEndpointAddress (EP3-IN)             
270         0x03,                   # bmAttributes  (interrupt)
271         64,0,                   # wMaxPacketSize (64)
272         10];
273     strDesc=[
274 # STRING descriptor 0--Language string
275 "\x04\x03\x09\x04",
276 # [
277 #         0x04,                 # bLength
278 #       0x03,                   # bDescriptorType = string
279 #       0x09,0x04               # wLANGID(L/H) = English-United Sates
280 # ],
281 # STRING descriptor 1--Manufacturer ID
282 "\x0c\x03M\x00a\x00x\x00i\x00m\x00",
283 # [
284 #         12,                   # bLength
285 #       0x03,                   # bDescriptorType = string
286 #       'M',0,'a',0,'x',0,'i',0,'m',0 # text in Unicode
287 # ], 
288 # STRING descriptor 2 - Product ID
289 "\x18\x03M\x00A\x00X\x003\x004\x002\x000\x00E\x00 \x00E\x00n\x00u\x00m\x00 \x00C\x00o\x00d\x00e\x00",
290 # [     24,                     # bLength
291 #       0x03,                   # bDescriptorType = string
292 #       'M',0,'A',0,'X',0,'3',0,'4',0,'2',0,'0',0,'E',0,' ',0,
293 #         'E',0,'n',0,'u',0,'m',0,' ',0,'C',0,'o',0,'d',0,'e',0
294 # ],
295
296
297 # STRING descriptor 3 - Serial Number ID
298 "\x14\x03S\x00/\x00N\x00 \x003\x004\x002\x000\x00E\x00"
299 # [       20,                   # bLength
300 #       0x03,                   # bDescriptorType = string
301 #       'S',0,                          
302 #       '/',0,
303 #       'N',0,
304 #       ' ',0,
305 #       '3',0,
306 #       '4',0,
307 #       '2',0,
308 #       '0',0,
309 #         'E',0,
310 # ]
311 ];
312     RepD=[
313         0x05,0x01,              # Usage Page (generic desktop)
314         0x09,0x06,              # Usage (keyboard)
315         0xA1,0x01,              # Collection
316         0x05,0x07,              #   Usage Page 7 (keyboard/keypad)
317         0x19,0xE0,              #   Usage Minimum = 224
318         0x29,0xE7,              #   Usage Maximum = 231
319         0x15,0x00,              #   Logical Minimum = 0
320         0x25,0x01,              #   Logical Maximum = 1
321         0x75,0x01,              #   Report Size = 1
322         0x95,0x08,              #   Report Count = 8
323         0x81,0x02,              #  Input(Data,Variable,Absolute)
324         0x95,0x01,              #   Report Count = 1
325         0x75,0x08,              #   Report Size = 8
326         0x81,0x01,              #  Input(Constant)
327         0x19,0x00,              #   Usage Minimum = 0
328         0x29,0x65,              #   Usage Maximum = 101
329         0x15,0x00,              #   Logical Minimum = 0,
330         0x25,0x65,              #   Logical Maximum = 101
331         0x75,0x08,              #   Report Size = 8
332         0x95,0x01,              #   Report Count = 1
333         0x81,0x00,              #  Input(Data,Variable,Array)
334         0xC0]
335     def send_descriptor(self,SUD):
336         """Send the USB descriptors based upon the setup data."""
337         desclen=0;
338         reqlen=ord(SUD[wLengthL])+256*ord(SUD[wLengthH]); #16-bit length
339         desctype=ord(SUD[wValueH]);
340         
341         if desctype==GD_DEVICE:
342             desclen=self.DD[0];
343             ddata=self.DD;
344         elif desctype==GD_CONFIGURATION:
345             desclen=self.CD[2];
346             ddata=self.CD;
347         elif desctype==GD_STRING:
348             desclen=self.strDesc[ord(SUD[wValueL])][0];
349             ddata=self.strDesc[ord(SUD[wValueL])];
350         elif desctype==GD_REPORT:
351             desclen=self.CD[25];
352             ddata=self.RepD;
353         
354         #TODO Configuration, String, Hid, and Report
355         
356         if desclen>0:
357             sendlen=min(reqlen,desclen);
358             self.writebytes(rEP0FIFO,ddata);
359             self.wregAS(rEP0BC,sendlen);
360         else:
361             print "Stalling in send_descriptor() for lack of handler for %02x." % desctype;
362             self.STALL_EP0();
363     def set_configuration(self,SUD):
364         """Set the configuration."""
365         bmSUSPIE=0x10;
366         configval=ord(SUD[wValueL]);
367         if(configval>0):
368             self.SETBIT(rUSBIEN,bmSUSPIE);
369         self.rregAS(rFNADDR);
370     def get_status(self,SUD):
371         """Get the USB Setup Status."""
372         testbyte=ord(SUD[bmRequestType])
373         
374         #Toward Device
375         if testbyte==0x80:
376             self.wreg(rEP0FIFO,0x03); #Enable RWU and self-powered
377             self.wreg(rEP0FIFO,0x00); #Second byte is always zero.
378             self.wregAS(rEP0BC,2);    #Load byte count, arm transfer, and ack CTL.
379         #Toward Interface
380         elif testbyte==0x81:
381             self.wreg(rEP0FIFO,0x00);
382             self.wreg(rEP0FIFO,0x00); #Second byte is always zero.
383             self.wregAS(rEP0BC,2);
384         #Toward Endpoint
385         elif testbyte==0x82:
386             if(ord(SUD[wIndexL])==0x83):
387                 self.wreg(rEP0FIFO,0x01); #Stall EP3
388                 self.wreg(rEP0FIFO,0x00); #Second byte is always zero.
389                 self.wregAS(rEP0BC,2);
390             else:
391                 self.STALL_EP0();
392         else:
393             self.STALL_EP0();
394     def service_irqs(self):
395         """Handle USB interrupt events."""
396         
397         epirq=self.rreg(rEPIRQ);
398         usbirq=self.rreg(rUSBIRQ);
399         
400         #Are we being asked for setup data?
401         if(epirq&bmSUDAVIRQ): #Setup Data Requested
402             self.wreg(rEPIRQ,bmSUDAVIRQ); #Clear the bit
403             self.do_SETUP();
404         if(epirq&bmIN3BAVIRQ): #EN3-IN packet
405             self.do_IN3();
406         
407     
408     typephase=0;
409     typestring="                      Python does USB HID!";
410     typepos=0;
411     
412     def asc2hid(self,ascii):
413         """Translate ASCII to an USB keycode."""
414         a=ascii;
415         if a>='a' and a<='z':
416             return ord(a)-ord('a')+4;
417         elif a>='A' and a<='Z':
418             return ord(a)-ord('A')+4;
419         elif a==' ':
420             return 0x2C; #space
421         else:
422             return 0; #key-up
423     def type_IN3(self):
424         """Type next letter in buffer."""
425         if self.typepos>=len(self.typestring):
426             self.typeletter(0);
427         elif self.typephase==0:
428             self.typephase=1;
429             self.typeletter(0);
430         else:
431             typephase=0;
432             self.typeletter(self.typestring[self.typepos]);
433             self.typepos=self.typepos+1;
434         return;
435     def typeletter(self,key):
436         """Type a letter on IN3.  Zero for keyup."""
437         #if type(key)==str: key=ord(key);
438         #Send a key-up.
439         self.wreg(rEP3INFIFO,0);
440         self.wreg(rEP3INFIFO,0);
441         self.wreg(rEP3INFIFO,self.asc2hid(key));
442         self.wreg(rEP3INBC,3);
443     def do_IN3(self):
444         """Handle IN3 event."""
445         #Don't bother clearing interrupt flag, that's done by sending the reply.
446         self.type_IN3();
447