added comments
[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 rIOPINS1=20  #Same as rIOPINS
36 rIOPINS2=21
37 rHIRQ=25
38 rHIEN=26
39 rMODE=27
40 rPERADDR=28
41 rHCTL=29
42 rHXFR=30
43 rHRSL=31
44
45 #Host mode registers.
46 rRCVFIFO =1
47 rSNDFIFO =2
48 rRCVBC   =6
49 rSNDBC   =7
50 rHIRQ    =25
51
52
53 # R11 EPIRQ register bits
54 bmSUDAVIRQ =0x20
55 bmIN3BAVIRQ =0x10
56 bmIN2BAVIRQ =0x08
57 bmOUT1DAVIRQ= 0x04
58 bmOUT0DAVIRQ= 0x02
59 bmIN0BAVIRQ =0x01
60
61 # R12 EPIEN register bits
62 bmSUDAVIE   =0x20
63 bmIN3BAVIE  =0x10
64 bmIN2BAVIE  =0x08
65 bmOUT1DAVIE =0x04
66 bmOUT0DAVIE =0x02
67 bmIN0BAVIE  =0x01
68
69
70
71
72 # ************************
73 # Standard USB Requests
74 SR_GET_STATUS           =0x00   # Get Status
75 SR_CLEAR_FEATURE        =0x01   # Clear Feature
76 SR_RESERVED             =0x02   # Reserved
77 SR_SET_FEATURE          =0x03   # Set Feature
78 SR_SET_ADDRESS          =0x05   # Set Address
79 SR_GET_DESCRIPTOR       =0x06   # Get Descriptor
80 SR_SET_DESCRIPTOR       =0x07   # Set Descriptor
81 SR_GET_CONFIGURATION    =0x08   # Get Configuration
82 SR_SET_CONFIGURATION    =0x09   # Set Configuration
83 SR_GET_INTERFACE        =0x0a   # Get Interface
84 SR_SET_INTERFACE        =0x0b   # Set Interface
85
86 # Get Descriptor codes  
87 GD_DEVICE               =0x01   # Get device descriptor: Device
88 GD_CONFIGURATION        =0x02   # Get device descriptor: Configuration
89 GD_STRING               =0x03   # Get device descriptor: String
90 GD_HID                  =0x21   # Get descriptor: HID
91 GD_REPORT               =0x22   # Get descriptor: Report
92
93 # SETUP packet header offsets
94 bmRequestType           =0
95 bRequest                =1
96 wValueL                 =2
97 wValueH                 =3
98 wIndexL                 =4
99 wIndexH                 =5
100 wLengthL                =6
101 wLengthH                =7
102
103 # HID bRequest values
104 GET_REPORT              =1
105 GET_IDLE                =2
106 GET_PROTOCOL            =3
107 SET_REPORT              =9
108 SET_IDLE                =0x0A
109 SET_PROTOCOL            =0x0B
110 INPUT_REPORT            =1
111
112 # PINCTL bits
113 bmEP3INAK   =0x80
114 bmEP2INAK   =0x40
115 bmEP1INAK   =0x20
116 bmFDUPSPI   =0x10
117 bmINTLEVEL  =0x08
118 bmPOSINT    =0x04
119 bmGPXB      =0x02
120 bmGPXA      =0x01
121
122 # rUSBCTL bits
123 bmHOSCSTEN  =0x80
124 bmVBGATE    =0x40
125 bmCHIPRES   =0x20
126 bmPWRDOWN   =0x10
127 bmCONNECT   =0x08
128 bmSIGRWU    =0x04
129
130 # USBIRQ bits
131 bmURESDNIRQ =0x80
132 bmVBUSIRQ   =0x40
133 bmNOVBUSIRQ =0x20
134 bmSUSPIRQ   =0x10
135 bmURESIRQ   =0x08
136 bmBUSACTIRQ =0x04
137 bmRWUDNIRQ  =0x02
138 bmOSCOKIRQ  =0x01
139
140 # MODE bits
141 bmHOST          =0x01
142 bmLOWSPEED      =0x02
143 bmHUBPRE        =0x04
144 bmSOFKAENAB     =0x08
145 bmSEPIRQ        =0x10
146 bmDELAYISO      =0x20
147 bmDMPULLDN      =0x40
148 bmDPPULLDN      =0x80
149
150 # PERADDR/HCTL bits
151 bmBUSRST        =0x01
152 bmFRMRST        =0x02
153 bmSAMPLEBUS     =0x04
154 bmSIGRSM        =0x08
155 bmRCVTOG0       =0x10
156 bmRCVTOG1       =0x20
157 bmSNDTOG0       =0x40
158 bmSNDTOG1       =0x80
159
160 # rHXFR bits
161 # Host XFR token values for writing the HXFR register (R30).
162 # OR this bit field with the endpoint number in bits 3:0
163 tokSETUP  =0x10  # HS=0, ISO=0, OUTNIN=0, SETUP=1
164 tokIN     =0x00  # HS=0, ISO=0, OUTNIN=0, SETUP=0
165 tokOUT    =0x20  # HS=0, ISO=0, OUTNIN=1, SETUP=0
166 tokINHS   =0x80  # HS=1, ISO=0, OUTNIN=0, SETUP=0
167 tokOUTHS  =0xA0  # HS=1, ISO=0, OUTNIN=1, SETUP=0 
168 tokISOIN  =0x40  # HS=0, ISO=1, OUTNIN=0, SETUP=0
169 tokISOOUT =0x60  # HS=0, ISO=1, OUTNIN=1, SETUP=0
170
171 # rRSL bits
172 bmRCVTOGRD   =0x10
173 bmSNDTOGRD   =0x20
174 bmKSTATUS    =0x40
175 bmJSTATUS    =0x80
176 # Host error result codes, the 4 LSB's in the HRSL register.
177 hrSUCCESS   =0x00
178 hrBUSY      =0x01
179 hrBADREQ    =0x02
180 hrUNDEF     =0x03
181 hrNAK       =0x04
182 hrSTALL     =0x05
183 hrTOGERR    =0x06
184 hrWRONGPID  =0x07
185 hrBADBC     =0x08
186 hrPIDERR    =0x09
187 hrPKTERR    =0x0A
188 hrCRCERR    =0x0B
189 hrKERR      =0x0C
190 hrJERR      =0x0D
191 hrTIMEOUT   =0x0E
192 hrBABBLE    =0x0F
193
194 # HIRQ bits
195 bmBUSEVENTIRQ   =0x01   # indicates BUS Reset Done or BUS Resume     
196 bmRWUIRQ        =0x02
197 bmRCVDAVIRQ     =0x04
198 bmSNDBAVIRQ     =0x08
199 bmSUSDNIRQ      =0x10
200 bmCONDETIRQ     =0x20
201 bmFRAMEIRQ      =0x40
202 bmHXFRDNIRQ     =0x80
203
204 class GoodFETMAXUSB(GoodFET):
205     MAXUSBAPP=0x40;
206     usbverbose=False;
207     
208     def service_irqs(self):
209         """Handle USB interrupt events."""
210         epirq=self.rreg(rEPIRQ);
211         usbirq=self.rreg(rUSBIRQ);
212         
213         
214         #Are we being asked for setup data?
215         if(epirq&bmSUDAVIRQ): #Setup Data Requested
216             self.wreg(rEPIRQ,bmSUDAVIRQ); #Clear the bit
217             self.do_SETUP();
218         if(epirq&bmOUT1DAVIRQ): #OUT1-OUT packet
219             self.do_OUT1();
220             self.wreg(rEPIRQ,bmOUT1DAVIRQ); #Clear the bit *AFTER* servicing.
221         if(epirq&bmIN3BAVIRQ): #IN3-IN packet
222             self.do_IN3();
223             #self.wreg(rEPIRQ,bmIN3BAVIRQ); #Clear the bit
224         if(epirq&bmIN2BAVIRQ): #IN2 packet
225             self.do_IN2();
226             #self.wreg(rEPIRQ,bmIN2BAVIRQ); #Clear the bit
227         #else:
228         #    print "No idea how to service this IRQ: %02x" % epirq;
229     def do_IN2(self):
230         """Overload this."""
231     def do_IN3(self):
232         """Overload this."""
233     def do_OUT1(self):
234         """Overload this."""
235         if self.usbverbose: print "Ignoring an OUT1 interrupt.";
236     def setup2str(self,SUD):
237         """Converts the header of a setup packet to a string."""
238         return "bmRequestType=0x%02x, bRequest=0x%02x, wValue=0x%04x, wIndex=0x%04x, wLength=0x%04x" % (
239                 ord(SUD[0]), ord(SUD[1]),
240                 ord(SUD[2])+(ord(SUD[3])<<8),
241                 ord(SUD[4])+(ord(SUD[5])<<8),
242                 ord(SUD[6])+(ord(SUD[7])<<8)
243                 );
244     
245     def MAXUSBsetup(self):
246         """Move the FET into the MAXUSB application."""
247         self.writecmd(self.MAXUSBAPP,0x10,0,self.data); #MAXUSB/SETUP
248         self.writecmd(self.MAXUSBAPP,0x10,0,self.data); #MAXUSB/SETUP
249         self.writecmd(self.MAXUSBAPP,0x10,0,self.data); #MAXUSB/SETUP
250         print "Connected to MAX342x Rev. %x" % (self.rreg(rREVISION));
251         self.wreg(rPINCTL,0x18); #Set duplex and negative INT level.
252         
253     def MAXUSBtrans8(self,byte):
254         """Read and write 8 bits by MAXUSB."""
255         data=self.MAXUSBtrans([byte]);
256         return ord(data[0]);
257     
258     def MAXUSBtrans(self,data):
259         """Exchange data by MAXUSB."""
260         self.data=data;
261         self.writecmd(self.MAXUSBAPP,0x00,len(data),data);
262         return self.data;
263
264     def rreg(self,reg):
265         """Peek 8 bits from a register."""
266         data=[reg<<3,0];
267         self.writecmd(self.MAXUSBAPP,0x00,len(data),data);
268         return ord(self.data[1]);
269     def rregAS(self,reg):
270         """Peek 8 bits from a register, setting AS."""
271         data=[(reg<<3)|1,0];
272         self.writecmd(self.MAXUSBAPP,0x00,len(data),data);
273         return ord(self.data[1]);
274     def wreg(self,reg,value):
275         """Poke 8 bits into a register."""
276         data=[(reg<<3)|2,value];
277         self.writecmd(self.MAXUSBAPP,0x00,len(data),data);        
278         return value;
279     def wregAS(self,reg,value):
280         """Poke 8 bits into a register, setting AS."""
281         data=[(reg<<3)|3,value];
282         self.writecmd(self.MAXUSBAPP,0x00,len(data),data);        
283         return value;
284     def readbytes(self,reg,length):
285         """Peek some bytes from a register."""
286         data=[(reg<<3)]+range(0,length);
287         self.writecmd(self.MAXUSBAPP,0x00,len(data),data);
288         toret=self.data[1:len(self.data)];
289         ashex="";
290         for foo in toret:
291             ashex=ashex+(" %02x"%ord(foo));
292         if self.usbverbose: print "GET   %02x==%s" % (reg,ashex);
293         return toret;
294     def readbytesAS(self,reg,length):
295         """Peek some bytes from a register, acking prior transfer."""
296         data=[(reg<<3)|1]+range(0,length);
297         self.writecmd(self.MAXUSBAPP,0x00,len(data),data);
298         toret=self.data[1:len(self.data)];
299         ashex="";
300         for foo in toret:
301             ashex=ashex+(" %02x"%ord(foo));
302         if self.usbverbose: print "GETAS %02x==%s" % (reg,ashex);
303         return toret;
304     def fifo_ep3in_tx(self,data):
305         """Sends the data out of EP3 in 64-byte chunks."""
306         #Wait for the buffer to be free before starting.
307         while not(self.rreg(rEPIRQ)&bmIN3BAVIRQ): pass;
308         
309         count=len(data);
310         pos=0;
311         while count>0:
312             #Send 64-byte chunks or the remainder.
313             c=min(count,64);
314             self.writebytes(rEP3INFIFO,
315                             data[pos:pos+c]);
316             self.wregAS(rEP3INBC,c);
317             count=count-c;
318             pos=pos+c;
319             
320             #Wait for the buffer to be free before continuing.
321             while not(self.rreg(rEPIRQ)&bmIN3BAVIRQ): pass;
322             
323         return;
324         
325     def ctl_write_nd(self,request):
326         """Control Write with no data stage.  Assumes PERADDR is set
327         and the SUDFIFO contains the 8 setup bytes.  Returns with
328         result code = HRSLT[3:0] (HRSL register).  If there is an
329         error, the 4MSBits of the returned value indicate the stage 1
330         or 2."""
331         
332         # 1. Send the SETUP token and 8 setup bytes. 
333         # Should ACK immediately.
334         self.writebytes(rSUDFIFO,request);
335         resultcode=self.send_packet(tokSETUP,0); #SETUP packet to EP0.
336         if resultcode: return resultcode;
337         
338         # 2. No data stage, so the last operation is to send an IN
339         # token to the peripheral as the STATUS (handhsake) stage of
340         # this control transfer.  We should get NAK or the DATA1 PID.
341         # When we get back to the DATA1 PID the 3421 automatically
342         # sends the closing NAK.
343         resultcode=self.send_packet(tokINHS,0); #Function takes care of retries.
344         if resultcode: return resultcode;
345         
346         return 0;
347         
348         
349     def ctl_read(self,request):
350         """Control read transfer, used in Host mode."""
351         resultcode=0;
352         bytes_to_read=request[6]+256*request[7];
353         
354         ##SETUP packet
355         self.writebytes(rSUDFIFO,request);     #Load the FIFO
356         resultcode=self.send_packet(tokSETUP,0); #SETUP packet to EP0
357         if resultcode:
358             print "Failed to get ACK on SETUP request in ctl_read()."
359             return resultcode;
360         
361         self.wreg(rHCTL,bmRCVTOG1);              #FIRST data packet in CTL transfer uses DATA1 toggle.
362         resultcode=self.IN_Transfer(0,bytes_to_read);
363         if resultcode:
364             print "Failed on IN Transfer in ctl_read()";
365             return resultcode;
366         
367         self.IN_nak_count=self.nak_count;
368         
369         #The OUT status stage.
370         resultcode=self.send_packet(tokOUTHS,0);
371         if resultcode:
372             print "Failed on OUT Status stage in ctl_read()";
373             return resultcode;
374         
375         return 0; #Success
376     
377     xfrdata=[]; #Ugly variable used only by a few functions.  FIXME
378     def IN_Transfer(self,endpoint,INbytes):
379         """Does an IN transfer to an endpoint, used for Host mode."""
380         xfrsize=INbytes;
381         xfrlen=0;
382         self.xfrdata=[];
383         
384         while 1:
385             resultcode=self.send_packet(tokIN,endpoint); #IN packet to EP. NAKS taken care of.
386             if resultcode: return resultcode;
387             
388             pktsize=self.rreg(rRCVBC); #Numer of RXed bytes.
389             
390             #Very innefficient, move this to C if performance is needed.
391             for j in range(0,pktsize):
392                 self.xfrdata=self.xfrdata+[self.rreg(rRCVFIFO)];
393             xfrsize=self.xfrdata[0];
394             self.wreg(rHIRQ,bmRCVDAVIRQ); #Clear IRQ
395             xfrlen=xfrlen+pktsize; #Add byte count to total transfer length.
396             
397             #print "%i / %i" % (xfrlen,xfrsize)
398             
399             #Packet is complete if:
400             # 1. The device sent a short packet, <maxPacketSize
401             # 2. INbytes have been transfered.
402             if (pktsize<self.maxPacketSize) or (xfrlen>=xfrsize):
403                 self.last_transfer_size=xfrlen;
404                 ashex="";
405                 for foo in self.xfrdata:
406                     ashex=ashex+(" %02x"%foo);
407                 #print "INPACKET EP%i==%s (0x%02x bytes remain)" % (endpoint,ashex,xfrsize);
408                 return resultcode;
409
410     RETRY_LIMIT=3;
411     NAK_LIMIT=300;
412     def send_packet(self,token,endpoint):
413         """Send a packet to an endpoint as the Host, taking care of NAKs.
414         Don't use this for device code."""
415         self.retry_count=0;
416         self.nak_count=0;
417         
418         #Repeat until NAK_LIMIT or RETRY_LIMIT is reached.
419         while self.nak_count<self.NAK_LIMIT and self.retry_count<self.RETRY_LIMIT:
420             self.wreg(rHXFR,(token|endpoint)); #launch the transfer
421             while not (self.rreg(rHIRQ) & bmHXFRDNIRQ):
422                 # wait for the completion IRQ
423                 pass;
424             self.wreg(rHIRQ,bmHXFRDNIRQ);           #Clear IRQ
425             resultcode = (self.rreg(rHRSL) & 0x0F); # get the result
426             if (resultcode==hrNAK):
427                 self.nak_count=self.nak_count+1;
428             elif (resultcode==hrTIMEOUT):
429                 self.retry_count=self.retry_count+1;
430             else:
431                 #Success!
432                 return resultcode;
433         return resultcode;
434             
435     def writebytes(self,reg,tosend):
436         """Poke some bytes into a register."""
437         data="";
438         if type(tosend)==str:
439             data=chr((reg<<3)|3)+tosend;
440             if self.usbverbose: print "PUT %02x:=%s (0x%02x bytes)" % (reg,tosend,len(data))
441         else:
442             data=[(reg<<3)|3]+tosend;
443             ashex="";
444             for foo in tosend:
445                 ashex=ashex+(" %02x"%foo);
446             if self.usbverbose: print "PUT %02x:=%s (0x%02x bytes)" % (reg,ashex,len(data))
447         self.writecmd(self.MAXUSBAPP,0x00,len(data),data);
448     def usb_connect(self):
449         """Connect the USB port."""
450         
451         #disconnect D+ pullup if host turns off VBUS
452         self.wreg(rUSBCTL,bmVBGATE|bmCONNECT);
453     def usb_disconnect(self):
454         """Disconnect the USB port."""
455         self.wreg(rUSBCTL,bmVBGATE);
456     def STALL_EP0(self,SUD=None):
457         """Stall for an unknown SETUP event."""
458         if SUD==None:
459             print "Stalling EP0.";
460         else:
461             print "Stalling EPO for %s" % self.setup2str(SUD);
462         self.wreg(rEPSTALLS,0x23); #All three stall bits.
463     def SETBIT(self,reg,val):
464         """Set a bit in a register."""
465         self.wreg(reg,self.rreg(reg)|val);
466     def vbus_on(self):
467         """Turn on the target device."""
468         self.wreg(rIOPINS2,(self.rreg(rIOPINS2)|0x08));
469     def vbus_off(self):
470         """Turn off the target device's power."""
471         self.wreg(rIOPINS2,0x00);
472     def reset_host(self):
473         """Resets the chip into host mode."""
474         self.wreg(rUSBCTL,bmCHIPRES); #Stop the oscillator.
475         self.wreg(rUSBCTL,0x00);      #restart it.
476         
477         #FIXME: Why does the OSC line never settle?
478         #Code works without it.
479         
480         #print "Waiting for PLL to sabilize.";
481         #while self.rreg(rUSBIRQ)&bmOSCOKIRQ:
482         #    #Hang until the PLL stabilizes.
483         #    pass;
484         #print "Stable.";
485
486 class GoodFETMAXUSBHost(GoodFETMAXUSB):
487     """This is a class for implemented a minimal USB host.
488     It's intended for fuzzing, rather than for daily use."""
489     def hostinit(self):
490         """Initialize the MAX3421 as a USB Host."""
491         self.usb_connect();
492         print "Enabling host mode.";
493         self.wreg(rPINCTL,(bmFDUPSPI|bmPOSINT));
494         print "Resetting host.";
495         self.reset_host();
496         self.vbus_off();
497         time.sleep(0.2);
498         print "Powering host.";
499         self.vbus_on();
500         
501         #self.hostrun();
502     def hostrun(self):
503         """Run as a minimal host and dump the config tables."""
504         while 1:
505             self.detect_device();
506             time.sleep(0.2);
507             self.enumerate_device();
508             self.wait_for_disconnect();
509     def detect_device(self):
510         """Waits for a device to be inserted and then returns."""
511         busstate=0;
512         
513         #Activate host mode and turn on 15K pulldown resistors on D+ and D-.
514         self.wreg(rMODE,(bmDPPULLDN|bmDMPULLDN|bmHOST));
515         #Clear connection detect IRQ.
516         self.wreg(rHIRQ,bmCONDETIRQ);
517         
518         print "Waiting for a device connection.";
519         while busstate==0:
520             self.wreg(rHCTL,bmSAMPLEBUS); #Update JSTATUS and KSTATUS bits.
521             busstate=self.rreg(rHRSL) & (bmJSTATUS|bmKSTATUS);
522             
523         if busstate==bmJSTATUS:
524             print "Detected Full-Speed Device.";
525             self.wreg(rMODE,(bmDPPULLDN|bmDMPULLDN|bmHOST|bmSOFKAENAB));
526         elif busstate==bmKSTATUS:
527             print "Detected Low-Speed Device.";
528             self.wreg(rMODE,(bmDPPULLDN|bmDMPULLDN|bmHOST|bmLOWSPEED|bmSOFKAENAB));
529         else:
530             print "Not sure whether this is Full-Speed or Low-Speed.  Please investigate.";
531     def wait_for_disconnect(self):
532         """Wait for a device to be disconnected."""
533         print "Waiting for a device disconnect.";
534         
535         self.wreg(rHIRQ,bmCONDETIRQ); #Clear disconnect IRQ
536         while not (self.rreg(rHIRQ) & bmCONDETIRQ):
537             #Wait for IRQ to change.
538             pass;
539         
540         #Turn off markers.
541         self.wreg(rMODE,bmDPPULLDN|bmDMPULLDN|bmHOST);
542         print "Device disconnected.";
543         self.wreg(rIOPINS2,(self.rreg(rIOPINS2) & ~0x04)); #HL1_OFF
544         self.wreg(rIOPINS1,(self.rreg(rIOPINS1) & ~0x02)); #HL4_OFF
545
546     def enumerate_device(self):
547         """Enumerates a device on the present port."""
548         
549         Set_Address_to_7 = [0x00,0x05,0x07,0x00,0x00,0x00,0x00,0x00];
550         Get_Descriptor_Device = [0x80,0x06,0x00,0x01,0x00,0x00,0x00,0x00]; #len filled in
551         Get_Descriptor_Config = [0x80,0x06,0x00,0x02,0x00,0x00,0x00,0x00];
552         
553         
554         print "Issuing USB bus reset.";
555         self.wreg(rHCTL,bmBUSRST);
556         while self.rreg(rHCTL) & bmBUSRST:
557             #Wait for reset to complete.
558             pass;
559         
560         time.sleep(0.2);
561         
562         #Get the device descriptor.
563         self.wreg(rPERADDR,0); #First request to address 0.
564         self.maxPacketSize=8; #Only safe value for first check.
565         Get_Descriptor_Device[6]=8; # wLengthL
566         Get_Descriptor_Device[7]=0; # wLengthH
567         
568         print "Fetching 8 bytes of Device Descriptor.";
569         self.ctl_read(Get_Descriptor_Device); # Get device descriptor into self.xfrdata;
570         self.maxPacketSize=self.xfrdata[7];
571         print "EP0 maxPacketSize is %02i bytes." % self.maxPacketSize;
572         
573         # Issue another USB bus reset
574         print "Resetting the bus again."
575         self.wreg(rHCTL,bmBUSRST);
576         while self.rreg(rHCTL) & bmBUSRST:
577             #Wait for reset to complete.
578             pass;
579         time.sleep(0.2);
580         
581         # Set_Address to 7 (Note: this request goes to address 0, already set in PERADDR register).
582         print "Setting address to 0x07";
583         HR = self.ctl_write_nd(Set_Address_to_7);   # CTL-Write, no data stage
584         #if(print_error(HR)) return;
585         
586         time.sleep(0.002);           # Device gets 2 msec recovery time
587         self.wreg(rPERADDR,7);       # now all transfers go to addr 7
588         
589         
590         #Get the device descriptor at the assigned address.
591         Get_Descriptor_Device[6]=0x12; #Fill in real descriptor length.
592         print "Fetching Device Descriptor."
593         self.ctl_read(Get_Descriptor_Device); #Result in self.xfrdata;
594         
595         self.descriptor=self.xfrdata;
596         self.VID        = self.xfrdata[8] + 256*self.xfrdata[9];
597         self.PID        = self.xfrdata[10]+ 256*self.xfrdata[11];
598         iMFG    = self.xfrdata[14];
599         iPROD   = self.xfrdata[15];
600         iSERIAL = self.xfrdata[16];
601         
602         self.manufacturer=self.getDescriptorString(iMFG);
603         self.product=self.getDescriptorString(iPROD);
604         self.serial=self.getDescriptorString(iSERIAL);
605         
606         self.printstrings();
607         
608     def printstrings(self):
609         print "Vendor  ID is %04x." % self.VID;
610         print "Product ID is %04x." % self.PID;
611         print "Manufacturer: %s" % self.manufacturer;
612         print "Product:      %s" % self.product;
613         print "Serial:       %s" % self.serial;
614         
615     def getDescriptorString(self, index):
616         """Grabs a string from the descriptor string table."""
617         # Get_Descriptor-String template. Code fills in idx at str[2].
618         Get_Descriptor_String = [0x80,0x06,index,0x03,0x00,0x00,0x40,0x00];
619         
620         if index==0: return "MISSING STRING";
621         
622         status=self.ctl_read(Get_Descriptor_String);
623         if status: return None;
624         
625         #Since we've got a string
626         toret="";
627         for c in self.xfrdata[2:len(self.xfrdata)]:
628             if c>0: toret=toret+chr(c);
629         return toret;
630 class GoodFETMAXUSBDevice(GoodFETMAXUSB):
631     
632     def send_descriptor(self,SUD):
633         """Send the USB descriptors based upon the setup data."""
634         desclen=0;
635         reqlen=ord(SUD[wLengthL])+256*ord(SUD[wLengthH]); #16-bit length
636         desctype=ord(SUD[wValueH]);
637         
638         if desctype==GD_DEVICE:
639             desclen=self.DD[0];
640             ddata=self.DD;
641         elif desctype==GD_CONFIGURATION:
642             desclen=self.CD[2];
643             ddata=self.CD;
644         elif desctype==GD_STRING:
645             desclen=ord(self.strDesc[ord(SUD[wValueL])][0]);
646             ddata=self.strDesc[ord(SUD[wValueL])];
647         elif desctype==GD_HID:
648             #Don't know how to do this yet.
649             pass;
650         elif desctype==GD_REPORT:
651             desclen=self.CD[25];
652             ddata=self.RepD;
653         #TODO Configuration, String, Hid, and Report
654         
655         if desclen>0:
656             #Reduce desclen if asked for fewer bytes.
657             desclen=min(reqlen,desclen);
658             #Send those bytes.
659             self.writebytes(rEP0FIFO,ddata[0:desclen]);
660             self.wregAS(rEP0BC,desclen);
661         else:
662             print "Stalling in send_descriptor() for lack of handler for %02x." % desctype;
663             self.STALL_EP0(SUD);
664     def set_configuration(self,SUD):
665         """Set the configuration."""
666         bmSUSPIE=0x10;
667         configval=ord(SUD[wValueL]);
668         if(configval>0):
669             self.SETBIT(rUSBIEN,bmSUSPIE);
670         self.rregAS(rFNADDR);
671 class GoodFETMAXUSBHID(GoodFETMAXUSBDevice):
672     """This is an example HID keyboard driver, loosely based on the
673     MAX3420 examples."""
674     def hidinit(self):
675         """Initialize a USB HID device."""
676         self.usb_disconnect();
677         self.usb_connect();
678         
679         self.hidrun();
680         
681     def hidrun(self):
682         """Main loop of the USB HID emulator."""
683         print "Starting a HID device.  This won't return.";
684         while 1:
685             self.service_irqs();
686     def do_SETUP(self):
687         """Handle USB Enumeration"""
688         
689         #Grab the SETUP packet from the buffer.
690         SUD=self.readbytes(rSUDFIFO,8);
691         
692         #Parse the SETUP packet
693         print "Handling a setup packet of %s" % self.setup2str(SUD);
694         
695         self.OsLastConfigType=ord(SUD[bmRequestType]);
696         self.typepos=0;
697         setuptype=(ord(SUD[bmRequestType])&0x60);
698         if setuptype==0x00:
699             self.std_request(SUD);
700         elif setuptype==0x20:
701             self.class_request(SUD);
702         elif setuptype==0x40:
703             self.vendor_request(SUD);
704         else:
705             print "Unknown request type 0x%02x." % ord(SUD[bmRequestType])
706             self.STALL_EP0(SUD);
707     def class_request(self,SUD):
708         """Handle a class request."""
709         print "Stalling a class request.";
710         self.STALL_EP0(SUD);
711     def vendor_request(self,SUD):
712         print "Stalling a vendor request.";
713         self.STALL_EP0(SUD);
714     def std_request(self,SUD):
715         """Handles a standard setup request."""
716         setuptype=ord(SUD[bRequest]);
717         if setuptype==SR_GET_DESCRIPTOR: self.send_descriptor(SUD);
718         #elif setuptype==SR_SET_FEATURE:
719         #    self.rregAS(rFNADDR);
720         #    # self.feature(1);
721         elif setuptype==SR_SET_CONFIGURATION: self.set_configuration(SUD);
722         elif setuptype==SR_GET_STATUS: self.get_status(SUD);
723         elif setuptype==SR_SET_ADDRESS: self.rregAS(rFNADDR);
724         elif setuptype==SR_GET_INTERFACE: self.get_interface(SUD);
725         else:
726             print "Stalling Unknown standard setup request type %02x" % setuptype;
727             self.STALL_EP0(SUD);
728     
729     def get_interface(self,SUD):
730         """Handles a setup request for SR_GET_INTERFACE."""
731         if ord(SUD[wIndexL]==0):
732             self.wreg(rEP0FIFO,0);
733             self.wregAS(rEP0BC,1);
734         else:
735             self.STALL_EP0(SUD);
736     
737     OsLastConfigType=-1;
738 #Device Descriptor
739     DD=[0x12,                   # bLength = 18d
740         0x01,                   # bDescriptorType = Device (1)
741         0x00,0x01,              # bcdUSB(L/H) USB spec rev (BCD)
742         0x00,0x00,0x00,         # bDeviceClass, bDeviceSubClass, bDeviceProtocol
743         0x40,                   # bMaxPacketSize0 EP0 is 64 bytes
744         0x6A,0x0B,              # idVendor(L/H)--Maxim is 0B6A
745         0x46,0x53,              # idProduct(L/H)--5346
746         0x34,0x12,              # bcdDevice--1234
747         1,2,3,                  # iManufacturer, iProduct, iSerialNumber
748         1];
749 #Configuration Descriptor
750     CD=[0x09,                   # bLength
751         0x02,                   # bDescriptorType = Config
752         0x22,0x00,              # wTotalLength(L/H) = 34 bytes
753         0x01,                   # bNumInterfaces
754         0x01,                   # bConfigValue
755         0x00,                   # iConfiguration
756         0xE0,                   # bmAttributes. b7=1 b6=self-powered b5=RWU supported
757         0x01,                   # MaxPower is 2 ma
758 # INTERFACE Descriptor
759         0x09,                   # length = 9
760         0x04,                   # type = IF
761         0x00,                   # IF #0
762         0x00,                   # bAlternate Setting
763         0x01,                   # bNum Endpoints
764         0x03,                   # bInterfaceClass = HID
765         0x00,0x00,              # bInterfaceSubClass, bInterfaceProtocol
766         0x00,                   # iInterface
767 # HID Descriptor--It's at CD[18]
768         0x09,                   # bLength
769         0x21,                   # bDescriptorType = HID
770         0x10,0x01,              # bcdHID(L/H) Rev 1.1
771         0x00,                   # bCountryCode (none)
772         0x01,                   # bNumDescriptors (one report descriptor)
773         0x22,                   # bDescriptorType       (report)
774         43,0,                   # CD[25]: wDescriptorLength(L/H) (report descriptor size is 43 bytes)
775 # Endpoint Descriptor
776         0x07,                   # bLength
777         0x05,                   # bDescriptorType (Endpoint)
778         0x83,                   # bEndpointAddress (EP3-IN)             
779         0x03,                   # bmAttributes  (interrupt)
780         64,0,                   # wMaxPacketSize (64)
781         10];
782     strDesc=[
783 # STRING descriptor 0--Language string
784 "\x04\x03\x09\x04",
785 # [
786 #         0x04,                 # bLength
787 #       0x03,                   # bDescriptorType = string
788 #       0x09,0x04               # wLANGID(L/H) = English-United Sates
789 # ],
790 # STRING descriptor 1--Manufacturer ID
791 "\x0c\x03M\x00a\x00x\x00i\x00m\x00",
792 # [
793 #         12,                   # bLength
794 #       0x03,                   # bDescriptorType = string
795 #       'M',0,'a',0,'x',0,'i',0,'m',0 # text in Unicode
796 # ], 
797 # STRING descriptor 2 - Product ID
798 "\x18\x03M\x00A\x00X\x003\x004\x002\x000\x00E\x00 \x00E\x00n\x00u\x00m\x00 \x00C\x00o\x00d\x00e\x00",
799 # [     24,                     # bLength
800 #       0x03,                   # bDescriptorType = string
801 #       'M',0,'A',0,'X',0,'3',0,'4',0,'2',0,'0',0,'E',0,' ',0,
802 #         'E',0,'n',0,'u',0,'m',0,' ',0,'C',0,'o',0,'d',0,'e',0
803 # ],
804
805
806 # STRING descriptor 3 - Serial Number ID
807 "\x14\x03S\x00/\x00N\x00 \x003\x004\x002\x000\x00E\x00"
808 # [       20,                   # bLength
809 #       0x03,                   # bDescriptorType = string
810 #       'S',0,                          
811 #       '/',0,
812 #       'N',0,
813 #       ' ',0,
814 #       '3',0,
815 #       '4',0,
816 #       '2',0,
817 #       '0',0,
818 #         'E',0,
819 # ]
820 ];
821     RepD=[
822         0x05,0x01,              # Usage Page (generic desktop)
823         0x09,0x06,              # Usage (keyboard)
824         0xA1,0x01,              # Collection
825         0x05,0x07,              #   Usage Page 7 (keyboard/keypad)
826         0x19,0xE0,              #   Usage Minimum = 224
827         0x29,0xE7,              #   Usage Maximum = 231
828         0x15,0x00,              #   Logical Minimum = 0
829         0x25,0x01,              #   Logical Maximum = 1
830         0x75,0x01,              #   Report Size = 1
831         0x95,0x08,              #   Report Count = 8
832         0x81,0x02,              #  Input(Data,Variable,Absolute)
833         0x95,0x01,              #   Report Count = 1
834         0x75,0x08,              #   Report Size = 8
835         0x81,0x01,              #  Input(Constant)
836         0x19,0x00,              #   Usage Minimum = 0
837         0x29,0x65,              #   Usage Maximum = 101
838         0x15,0x00,              #   Logical Minimum = 0,
839         0x25,0x65,              #   Logical Maximum = 101
840         0x75,0x08,              #   Report Size = 8
841         0x95,0x01,              #   Report Count = 1
842         0x81,0x00,              #  Input(Data,Variable,Array)
843         0xC0]
844
845     def get_status(self,SUD):
846         """Get the USB Setup Status."""
847         testbyte=ord(SUD[bmRequestType])
848         
849         #Toward Device
850         if testbyte==0x80:
851             self.wreg(rEP0FIFO,0x03); #Enable RWU and self-powered
852             self.wreg(rEP0FIFO,0x00); #Second byte is always zero.
853             self.wregAS(rEP0BC,2);    #Load byte count, arm transfer, and ack CTL.
854         #Toward Interface
855         elif testbyte==0x81:
856             self.wreg(rEP0FIFO,0x00);
857             self.wreg(rEP0FIFO,0x00); #Second byte is always zero.
858             self.wregAS(rEP0BC,2);
859         #Toward Endpoint
860         elif testbyte==0x82:
861             if(ord(SUD[wIndexL])==0x83):
862                 self.wreg(rEP0FIFO,0x01); #Stall EP3
863                 self.wreg(rEP0FIFO,0x00); #Second byte is always zero.
864                 self.wregAS(rEP0BC,2);
865             else:
866                 self.STALL_EP0(SUD);
867         else:
868             self.STALL_EP0(SUD);
869
870     typepos=0;
871     typestrings={
872         -1   : "Python does USB HID!\n",                # Unidentified OS.  This is the default typestring.
873         0x00 : "OSX Hosts don't recognize Maxim keyboards.\n",  # We have to identify as an Apple keyboard to get arround the unknown keyboard error.
874         0xA1 : "Python does USB HID on Linux!\n",
875         0x81 : "                                                                                             Python does USB HID on Windows!\n",        # Windows requires a bit of a delay.  Maybe we can watch for a keyboard reset command?
876     }
877     def typestring(self):
878         if self.typestrings.has_key(self.OsLastConfigType):
879             return self.typestrings[self.OsLastConfigType];
880         else:
881             return self.typestrings[-1];
882     # http://www.win.tue.nl/~aeb/linux/kbd/scancodes-14.html
883     # Escape=0x29 Backsp=0x2A Space=0x2C CapsLock=0x39 Menu=0x65
884     keymaps={
885         'en_US'  :[ '    abcdefghijklmnopqrstuvwxyz1234567890\n\e\7f\t -=[]\\\\;\'`,./',
886                     '''    \ 1\ 2\ 3\ 4\ 5\ 6\a\b  \v\f\r\ e\ f\10 \12 \14\15\16\17\18\19\1a''',        # LeftCtrl
887                     '    ABCDEFGHIJKLMNOPQRSTUVWXYZ!@#$%^&*()     {}?+||:"~<>?', # LeftShift
888                     '', # LeftCtrl & LeftShift
889                     '    \ea\eb\ec'], # LeftAlt
890         'Dvorak' :[ '    axje.uidchtnmbrl\'poygk,qf;1234567890\n\e\7f\t []/=\\\\s-`wvz',
891                     '''    \ 1\18 \ 5 \15 \ 4\ 3\b\14\ e\r\ 2\12\f \10\ f\19\a\v  \ 6                         \17\16\1a''',     # LeftCtrl
892                     '    AXJE UIDCHTNMBRL"POYGK<QF:!@#$%^&*()     {}?+||S_~WVZ', # LeftShift
893                     '', # LeftCtrl & LeftShift
894                     '    \ea\ex\ej'], # LeftAlt
895     }
896     layout='en_US';
897     def keymap(self):
898         return self.keymaps[self.layout];
899     modifiers={
900         'None':         0b00000000,
901         'LeftCtrl':     0b00000001,
902         'LeftShift':    0b00000010,
903         'LeftAlt':      0b00000100,
904         'LeftGUI':      0b00001000,
905         'RightCtrl':    0b00010000,
906         'RightShift':   0b00100000,
907         'RightAlt':     0b01000000,
908         'RightGUI':     0b10000000
909     }
910
911     def asc2hid(self,ascii):
912         """Translate ASCII to an USB keycode."""
913         if type(ascii)!=str:
914             return (0,0);               # Send NoEvent if not passed a character
915         if ascii==' ':
916             return (0,0x2C);            # space
917         for modset in self.keymap():
918             keycode=modset.find(ascii);
919             if keycode != -1:
920                 modifier = self.keymap().index(modset)
921                 return (modifier, keycode);
922         return (0,0);
923     def type_IN3(self):
924         """Type next letter in buffer."""
925         string=self.typestring();
926         if self.typepos>=len(string):
927             self.typeletter(0);         # Send NoEvent to indicate key-up
928             exit(0);
929             self.typepos=0;             # Repeat typestring forever!
930             # This would be a great place to enable a typethrough mode so the host operator can control the target
931         else:
932             if self.usbverbose:
933                 sys.stdout.write(string[self.typepos]);
934                 sys.stdout.flush();
935             self.typeletter(string[self.typepos]);
936             self.typepos+=1;
937         return;
938     def typeletter(self,key):
939         """Type a letter on IN3.  Zero for keyup."""
940         mod=0;
941         if type(key)==str:
942             (mod, key) = self.asc2hid(key);
943         self.wreg(rEP3INFIFO,mod);
944         self.wreg(rEP3INFIFO,0);
945         self.wreg(rEP3INFIFO,key);
946         self.wreg(rEP3INBC,3);
947     def do_IN3(self):
948         """Handle IN3 event."""
949         #Don't bother clearing interrupt flag, that's done by sending the reply.
950         if self.OsLastConfigType != -1: # Wait for some configuration before stuffing keycodes down the pipe
951             self.type_IN3();
952