8f05d43d7ec6c60ea90e0e0f727d0ccb0b1dc199
[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 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     def MAXUSBsetup(self):
207         """Move the FET into the MAXUSB application."""
208         self.writecmd(self.MAXUSBAPP,0x10,0,self.data); #MAXUSB/SETUP
209         print "Connected to MAX342x Rev. %x" % (self.rreg(rREVISION));
210         self.wreg(rPINCTL,0x18); #Set duplex and negative INT level.
211         
212     def MAXUSBtrans8(self,byte):
213         """Read and write 8 bits by MAXUSB."""
214         data=self.MAXUSBtrans([byte]);
215         return ord(data[0]);
216     
217     def MAXUSBtrans(self,data):
218         """Exchange data by MAXUSB."""
219         self.data=data;
220         self.writecmd(self.MAXUSBAPP,0x00,len(data),data);
221         return self.data;
222
223     def rreg(self,reg):
224         """Peek 8 bits from a register."""
225         data=[reg<<3,0];
226         self.writecmd(self.MAXUSBAPP,0x00,len(data),data);
227         return ord(self.data[1]);
228     def rregAS(self,reg):
229         """Peek 8 bits from a register, setting AS."""
230         data=[(reg<<3)|1,0];
231         self.writecmd(self.MAXUSBAPP,0x00,len(data),data);
232         return ord(self.data[1]);
233     def wreg(self,reg,value):
234         """Poke 8 bits into a register."""
235         data=[(reg<<3)|2,value];
236         self.writecmd(self.MAXUSBAPP,0x00,len(data),data);        
237         return value;
238     def wregAS(self,reg,value):
239         """Poke 8 bits into a register, setting AS."""
240         data=[(reg<<3)|3,value];
241         self.writecmd(self.MAXUSBAPP,0x00,len(data),data);        
242         return value;
243     def readbytes(self,reg,length):
244         """Peek some bytes from a register."""
245         data=[(reg<<3)]+range(0,length);
246         self.writecmd(self.MAXUSBAPP,0x00,len(data),data);
247         toret=self.data[1:len(self.data)];
248         ashex="";
249         for foo in toret:
250             ashex=ashex+(" %02x"%ord(foo));
251         print "GET %02x==%s" % (reg,ashex);
252         return toret;
253     def ctl_write_nd(self,request):
254         """Control Write with no data stage.  Assumes PERADDR is set
255         and the SUDFIFO contains the 8 setup bytes.  Returns with
256         result code = HRSLT[3:0] (HRSL register).  If there is an
257         error, the 4MSBits of the returned value indicate the stage 1
258         or 2."""
259         
260         # 1. Send the SETUP token and 8 setup bytes. 
261         # Should ACK immediately.
262         self.writebytes(rSUDFIFO,request);
263         resultcode=self.send_packet(tokSETUP,0); #SETUP packet to EP0.
264         if resultcode: return resultcode;
265         
266         # 2. No data stage, so the last operation is to send an IN
267         # token to the peripheral as the STATUS (handhsake) stage of
268         # this control transfer.  We should get NAK or the DATA1 PID.
269         # When we get back to the DATA1 PID the 3421 automatically
270         # sends the closing NAK.
271         resultcode=self.send_packet(tokINHS,0); #Function takes care of retries.
272         if resultcode: return resultcode;
273         
274         return 0;
275         
276         
277     def ctl_read(self,request):
278         """Control read transfer, used in Host mode."""
279         resultcode=0;
280         bytes_to_read=request[6]+256*request[7];
281         
282         ##SETUP packet
283         self.writebytes(rSUDFIFO,request);     #Load the FIFO
284         resultcode=self.send_packet(tokSETUP,0); #SETUP packet to EP0
285         if resultcode:
286             print "Failed to get ACK on SETUP request in ctl_read()."
287             return resultcode;
288         
289         self.wreg(rHCTL,bmRCVTOG1);              #FIRST data packet in CTL transfer uses DATA1 toggle.
290         resultcode=self.IN_Transfer(0,bytes_to_read);
291         if resultcode:
292             print "Failed on IN Transfer in ctl_read()";
293             return resultcode;
294         
295         self.IN_nak_count=self.nak_count;
296         
297         #The OUT status stage.
298         resultcode=self.send_packet(tokOUTHS,0);
299         if resultcode:
300             print "Failed on OUT Status stage in ctl_read()";
301             return resultcode;
302         
303         return 0; #Success
304     
305     xfrdata=[]; #Ugly variable used only by a few functions.  FIXME
306     def IN_Transfer(self,endpoint,INbytes):
307         """Does an IN transfer to an endpoint, used for Host mode."""
308         xfrsize=INbytes;
309         xfrlen=0;
310         self.xfrdata=[];
311         
312         while 1:
313             resultcode=self.send_packet(tokIN,endpoint); #IN packet to EP. NAKS taken care of.
314             if resultcode: return resultcode;
315             
316             pktsize=self.rreg(rRCVBC); #Numer of RXed bytes.
317             
318             #Very innefficient, move this to C if performance is needed.
319             for j in range(0,pktsize):
320                 self.xfrdata=self.xfrdata+[self.rreg(rRCVFIFO)];
321             self.wreg(rHIRQ,bmRCVDAVIRQ); #Clear IRQ
322             xfrlen=xfrlen+pktsize; #Add byte count to total transfer length.
323             
324             
325             #Packet is complete if:
326             # 1. The device sent a short packet, <maxPacketSize
327             # 2. INbytes have been transfered.
328             if (pktsize<self.maxPacketSize) or (xfrlen>=xfrsize):
329                 self.last_transfer_size=xfrlen;
330                 ashex="";
331                 for foo in self.xfrdata:
332                     ashex=ashex+(" %02x"%foo);
333                 print "INPACKET EP%i==%s" % (endpoint,ashex);
334                 return resultcode;
335
336     RETRY_LIMIT=3;
337     NAK_LIMIT=300;
338     def send_packet(self,token,endpoint):
339         """Send a packet to an endpoint as the Host, taking care of NAKs.
340         Don't use this for device code."""
341         self.retry_count=0;
342         self.nak_count=0;
343         
344         #Repeat until NAK_LIMIT or RETRY_LIMIT is reached.
345         while self.nak_count<self.NAK_LIMIT and self.retry_count<self.RETRY_LIMIT:
346             self.wreg(rHXFR,(token|endpoint)); #launch the transfer
347             while not (self.rreg(rHIRQ) & bmHXFRDNIRQ):
348                 # wait for the completion IRQ
349                 pass;
350             self.wreg(rHIRQ,bmHXFRDNIRQ);           #Clear IRQ
351             resultcode = (self.rreg(rHRSL) & 0x0F); # get the result
352             if (resultcode==hrNAK):
353                 self.nak_count=self.nak_count+1;
354             elif (resultcode==hrTIMEOUT):
355                 self.retry_count=self.retry_count+1;
356             else:
357                 #Success!
358                 return resultcode;
359         return resultcode;
360             
361     def writebytes(self,reg,tosend):
362         """Poke some bytes into a register."""
363         data="";
364         if type(tosend)==str:
365             data=chr((reg<<3)|2)+tosend;
366         else:
367             data=[(reg<<3)|2]+tosend;
368             ashex="";
369             for foo in tosend:
370                 ashex=ashex+(" %02x"%foo);
371             print "PUT %02x:=%s" % (reg,ashex)
372         self.writecmd(self.MAXUSBAPP,0x00,len(data),data);
373     def usb_connect(self):
374         """Connect the USB port."""
375         
376         #disconnect D+ pullup if host turns off VBUS
377         self.wreg(rUSBCTL,0x48);
378     def STALL_EP0(self):
379         """Stall for an unknown event."""
380         print "Stalling.";
381         self.wreg(rEPSTALLS,0x23); #All three stall bits.
382     def SETBIT(self,reg,val):
383         """Set a bit in a register."""
384         self.wreg(reg,self.rreg(reg)|val);
385     def vbus_on(self):
386         """Turn on the target device."""
387         self.wreg(rIOPINS2,(self.rreg(rIOPINS2)|0x08));
388     def vbus_off(self):
389         """Turn off the target device's power."""
390         self.wreg(rIOPINS2,0x00);
391     def reset_host(self):
392         """Resets the chip into host mode."""
393         self.wreg(rUSBCTL,bmCHIPRES); #Stop the oscillator.
394         self.wreg(rUSBCTL,0x00);      #restart it.
395         while self.rreg(rUSBIRQ)&bmOSCOKIRQ:
396             #Hang until the PLL stabilizes.
397             pass;
398
399 class GoodFETMAXUSBHost(GoodFETMAXUSB):
400     """This is a class for implemented a minimal USB host.
401     It's intended for fuzzing, rather than for daily use."""
402     def hostinit(self):
403         """Initialize the MAX3421 as a USB Host."""
404         self.usb_connect();
405         self.wreg(rPINCTL,(bmFDUPSPI|bmPOSINT));
406         self.reset_host();
407         self.vbus_off();
408         time.sleep(0.2);
409         self.vbus_on();
410         
411         #self.hostrun();
412     def hostrun(self):
413         """Run as a minimal host and dump the config tables."""
414         while 1:
415             self.detect_device();
416             time.sleep(0.2);
417             self.enumerate_device();
418             self.wait_for_disconnect();
419     def detect_device(self):
420         """Waits for a device to be inserted and then returns."""
421         busstate=0;
422         
423         #Activate host mode and turn on 15K pulldown resistors on D+ and D-.
424         self.wreg(rMODE,(bmDPPULLDN|bmDMPULLDN|bmHOST));
425         #Clear connection detect IRQ.
426         self.wreg(rHIRQ,bmCONDETIRQ);
427         
428         print "Waiting for a device connection.";
429         while busstate==0:
430             self.wreg(rHCTL,bmSAMPLEBUS); #Update JSTATUS and KSTATUS bits.
431             busstate=self.rreg(rHRSL) & (bmJSTATUS|bmKSTATUS);
432             
433         if busstate==bmJSTATUS:
434             print "Detected Full-Speed Device.";
435             self.wreg(rMODE,(bmDPPULLDN|bmDMPULLDN|bmHOST|bmSOFKAENAB));
436         elif busstate==bmKSTATUS:
437             print "Detected Low-Speed Device.";
438             self.wreg(rMODE,(bmDPPULLDN|bmDMPULLDN|bmHOST|bmLOWSPEED|bmSOFKAENAB));
439         else:
440             print "Not sure whether this is Full-Speed or Low-Speed.  Please investigate.";
441     def wait_for_disconnect(self):
442         """Wait for a device to be disconnected."""
443         print "Waiting for a device disconnect.";
444         
445         self.wreg(rHIRQ,bmCONDETIRQ); #Clear disconnect IRQ
446         while not (self.rreg(rHIRQ) & bmCONDETIRQ):
447             #Wait for IRQ to change.
448             pass;
449         
450         #Turn off markers.
451         self.wreg(rMODE,bmDPPULLDN|bmDMPULLDN|bmHOST);
452         print "Device disconnected.";
453         self.wreg(rIOPINS2,(self.rreg(rIOPINS2) & ~0x04)); #HL1_OFF
454         self.wreg(rIOPINS1,(self.rreg(rIOPINS1) & ~0x02)); #HL4_OFF
455
456     def enumerate_device(self):
457         """Enumerates a device on the present port."""
458         
459         Set_Address_to_7 = [0x00,0x05,0x07,0x00,0x00,0x00,0x00,0x00];
460         Get_Descriptor_Device = [0x80,0x06,0x00,0x01,0x00,0x00,0x00,0x00]; #len filled in
461         Get_Descriptor_Config = [0x80,0x06,0x00,0x02,0x00,0x00,0x00,0x00];
462         
463         
464         print "Issuing USB bus reset.";
465         self.wreg(rHCTL,bmBUSRST);
466         while self.rreg(rHCTL) & bmBUSRST:
467             #Wait for reset to complete.
468             pass;
469         
470         time.sleep(0.2);
471         
472         #Get the device descriptor.
473         self.wreg(rPERADDR,0); #First request to address 0.
474         self.maxPacketSize=8; #Only safe value for first check.
475         Get_Descriptor_Device[6]=8; # wLengthL
476         Get_Descriptor_Device[7]=0; # wLengthH
477         
478         print "Fetching 8 bytes of Device Descriptor.";
479         self.ctl_read(Get_Descriptor_Device); # Get device descriptor into self.xfrdata;
480         self.maxPacketSize=self.xfrdata[7];
481         print "EP0 maxPacketSize is %02i bytes." % self.maxPacketSize;
482         
483         # Issue another USB bus reset
484         print "Resetting the bus again."
485         self.wreg(rHCTL,bmBUSRST);
486         while self.rreg(rHCTL) & bmBUSRST:
487             #Wait for reset to complete.
488             pass;
489         time.sleep(0.2);
490         
491         # Set_Address to 7 (Note: this request goes to address 0, already set in PERADDR register).
492         print "Setting address to 0x07";
493         HR = self.ctl_write_nd(Set_Address_to_7);   # CTL-Write, no data stage
494         #if(print_error(HR)) return;
495         
496         time.sleep(0.002);           # Device gets 2 msec recovery time
497         self.wreg(rPERADDR,7);       # now all transfers go to addr 7
498         
499         
500         #Get the device descriptor at the assigned address.
501         Get_Descriptor_Device[6]=0x12; #Fill in real descriptor length.
502         print "Fetching Device Descriptor."
503         self.ctl_read(Get_Descriptor_Device); #Result in self.xfrdata;
504         
505         self.descriptor=self.xfrdata;
506         self.VID        = self.xfrdata[8] + 256*self.xfrdata[9];
507         self.PID        = self.xfrdata[10]+ 256*self.xfrdata[11];
508         iMFG    = self.xfrdata[14];
509         iPROD   = self.xfrdata[15];
510         iSERIAL = self.xfrdata[16];
511         
512         self.manufacturer=self.getDescriptorString(iMFG);
513         self.product=self.getDescriptorString(iPROD);
514         self.serial=self.getDescriptorString(iSERIAL);
515         
516         self.printstrings();
517         
518     def printstrings(self):
519         print "Vendor  ID is %04x." % self.VID;
520         print "Product ID is %04x." % self.PID;
521         print "Manufacturer: %s" % self.manufacturer;
522         print "Product:      %s" % self.product;
523         print "Serial:       %s" % self.serial;
524         
525     def getDescriptorString(self, index):
526         """Grabs a string from the descriptor string table."""
527         # Get_Descriptor-String template. Code fills in idx at str[2].
528         Get_Descriptor_String = [0x80,0x06,index,0x03,0x00,0x00,0x40,0x00];
529         
530         if index==0: return "MISSING STRING";
531         
532         status=self.ctl_read(Get_Descriptor_String);
533         if status: return None;
534         
535         #Since we've got a string
536         toret="";
537         for c in self.xfrdata[2:len(self.xfrdata)]:
538             if c>0: toret=toret+chr(c);
539         return toret;
540         
541 class GoodFETMAXUSBHID(GoodFETMAXUSB):
542     """This is an example HID keyboard driver, loosely based on the
543     MAX3420 examples."""
544     def hidinit(self):
545         """Initialize a USB HID device."""
546         self.usb_connect();
547         self.hidrun();
548         
549     def hidrun(self):
550         """Main loop of the USB HID emulator."""
551         print "Starting a HID device.  This won't return.";
552         while 1:
553             self.service_irqs();
554     def do_SETUP(self):
555         """Handle USB Enumeration"""
556         
557         #Grab the SETUP packet from the buffer.
558         SUD=self.readbytes(rSUDFIFO,8);
559         
560         #Parse the SETUP packet
561         print "Handling a setup packet type 0x%02x" % ord(SUD[bmRequestType]);
562         setuptype=(ord(SUD[bmRequestType])&0x60);
563         if setuptype==0x00:
564             self.std_request(SUD);
565         elif setuptype==0x20:
566             self.class_request(SUD);
567         elif setuptype==0x40:
568             self.vendor_request(SUD);
569         else:
570             print "Unknown request type 0x%02x." % ord(SUD[bmRequestType])
571             self.STALL_EP0();
572     def class_request(self,SUD):
573         """Handle a class request."""
574         print "Stalling a class request.";
575         self.STALL_EP0();
576     def vendor_request(self,SUD):
577         print "Stalling a vendor request.";
578         self.STALL_EP0();
579     def std_request(self,SUD):
580         """Handles a standard setup request."""
581         setuptype=ord(SUD[bRequest]);
582         if setuptype==SR_GET_DESCRIPTOR: self.send_descriptor(SUD);
583         elif setuptype==SR_SET_FEATURE: self.feature(1);
584         elif setuptype==SR_SET_CONFIGURATION: self.set_configuration(SUD);
585         elif setuptype==SR_GET_STATUS: self.get_status(SUD);
586         elif setuptype==SR_SET_ADDRESS: self.rregAS(rFNADDR);
587         elif setuptype==SR_GET_INTERFACE: self.get_interface(SUD);
588         else:
589             print "Stalling Unknown standard setup request type %02x" % setuptype;
590             
591             self.STALL_EP0();
592     
593     def get_interface(self,SUD):
594         """Handles a setup request for SR_GET_INTERFACE."""
595         if ord(SUD[wIndexL]==0):
596             self.wreg(rEP0FIFO,0);
597             self.wregAS(rEP0BC,1);
598         else:
599             self.STALL_EP0();
600     
601     #Device Descriptor
602     DD=[0x12,                   # bLength = 18d
603         0x01,                   # bDescriptorType = Device (1)
604         0x00,0x01,              # bcdUSB(L/H) USB spec rev (BCD)
605         0x00,0x00,0x00,         # bDeviceClass, bDeviceSubClass, bDeviceProtocol
606         0x40,                   # bMaxPacketSize0 EP0 is 64 bytes
607         0x6A,0x0B,              # idVendor(L/H)--Maxim is 0B6A
608         0x46,0x53,              # idProduct(L/H)--5346
609         0x34,0x12,              # bcdDevice--1234
610         1,2,3,                  # iManufacturer, iProduct, iSerialNumber
611         1];
612     #Configuration Descriptor
613     CD=[0x09,                   # bLength
614         0x02,                   # bDescriptorType = Config
615         0x22,0x00,              # wTotalLength(L/H) = 34 bytes
616         0x01,                   # bNumInterfaces
617         0x01,                   # bConfigValue
618         0x00,                   # iConfiguration
619         0xE0,                   # bmAttributes. b7=1 b6=self-powered b5=RWU supported
620         0x01,                   # MaxPower is 2 ma
621 # INTERFACE Descriptor
622         0x09,                   # length = 9
623         0x04,                   # type = IF
624         0x00,                   # IF #0
625         0x00,                   # bAlternate Setting
626         0x01,                   # bNum Endpoints
627         0x03,                   # bInterfaceClass = HID
628         0x00,0x00,              # bInterfaceSubClass, bInterfaceProtocol
629         0x00,                   # iInterface
630 # HID Descriptor--It's at CD[18]
631         0x09,                   # bLength
632         0x21,                   # bDescriptorType = HID
633         0x10,0x01,              # bcdHID(L/H) Rev 1.1
634         0x00,                   # bCountryCode (none)
635         0x01,                   # bNumDescriptors (one report descriptor)
636         0x22,                   # bDescriptorType       (report)
637         43,0,                   # CD[25]: wDescriptorLength(L/H) (report descriptor size is 43 bytes)
638 # Endpoint Descriptor
639         0x07,                   # bLength
640         0x05,                   # bDescriptorType (Endpoint)
641         0x83,                   # bEndpointAddress (EP3-IN)             
642         0x03,                   # bmAttributes  (interrupt)
643         64,0,                   # wMaxPacketSize (64)
644         10];
645     strDesc=[
646 # STRING descriptor 0--Language string
647 "\x04\x03\x09\x04",
648 # [
649 #         0x04,                 # bLength
650 #       0x03,                   # bDescriptorType = string
651 #       0x09,0x04               # wLANGID(L/H) = English-United Sates
652 # ],
653 # STRING descriptor 1--Manufacturer ID
654 "\x0c\x03M\x00a\x00x\x00i\x00m\x00",
655 # [
656 #         12,                   # bLength
657 #       0x03,                   # bDescriptorType = string
658 #       'M',0,'a',0,'x',0,'i',0,'m',0 # text in Unicode
659 # ], 
660 # STRING descriptor 2 - Product ID
661 "\x18\x03M\x00A\x00X\x003\x004\x002\x000\x00E\x00 \x00E\x00n\x00u\x00m\x00 \x00C\x00o\x00d\x00e\x00",
662 # [     24,                     # bLength
663 #       0x03,                   # bDescriptorType = string
664 #       'M',0,'A',0,'X',0,'3',0,'4',0,'2',0,'0',0,'E',0,' ',0,
665 #         'E',0,'n',0,'u',0,'m',0,' ',0,'C',0,'o',0,'d',0,'e',0
666 # ],
667
668
669 # STRING descriptor 3 - Serial Number ID
670 "\x14\x03S\x00/\x00N\x00 \x003\x004\x002\x000\x00E\x00"
671 # [       20,                   # bLength
672 #       0x03,                   # bDescriptorType = string
673 #       'S',0,                          
674 #       '/',0,
675 #       'N',0,
676 #       ' ',0,
677 #       '3',0,
678 #       '4',0,
679 #       '2',0,
680 #       '0',0,
681 #         'E',0,
682 # ]
683 ];
684     RepD=[
685         0x05,0x01,              # Usage Page (generic desktop)
686         0x09,0x06,              # Usage (keyboard)
687         0xA1,0x01,              # Collection
688         0x05,0x07,              #   Usage Page 7 (keyboard/keypad)
689         0x19,0xE0,              #   Usage Minimum = 224
690         0x29,0xE7,              #   Usage Maximum = 231
691         0x15,0x00,              #   Logical Minimum = 0
692         0x25,0x01,              #   Logical Maximum = 1
693         0x75,0x01,              #   Report Size = 1
694         0x95,0x08,              #   Report Count = 8
695         0x81,0x02,              #  Input(Data,Variable,Absolute)
696         0x95,0x01,              #   Report Count = 1
697         0x75,0x08,              #   Report Size = 8
698         0x81,0x01,              #  Input(Constant)
699         0x19,0x00,              #   Usage Minimum = 0
700         0x29,0x65,              #   Usage Maximum = 101
701         0x15,0x00,              #   Logical Minimum = 0,
702         0x25,0x65,              #   Logical Maximum = 101
703         0x75,0x08,              #   Report Size = 8
704         0x95,0x01,              #   Report Count = 1
705         0x81,0x00,              #  Input(Data,Variable,Array)
706         0xC0]
707     def send_descriptor(self,SUD):
708         """Send the USB descriptors based upon the setup data."""
709         desclen=0;
710         reqlen=ord(SUD[wLengthL])+256*ord(SUD[wLengthH]); #16-bit length
711         desctype=ord(SUD[wValueH]);
712         
713         if desctype==GD_DEVICE:
714             desclen=self.DD[0];
715             ddata=self.DD;
716         elif desctype==GD_CONFIGURATION:
717             desclen=self.CD[2];
718             ddata=self.CD;
719         elif desctype==GD_STRING:
720             desclen=self.strDesc[ord(SUD[wValueL])][0];
721             ddata=self.strDesc[ord(SUD[wValueL])];
722         elif desctype==GD_REPORT:
723             desclen=self.CD[25];
724             ddata=self.RepD;
725         
726         #TODO Configuration, String, Hid, and Report
727         
728         if desclen>0:
729             sendlen=min(reqlen,desclen);
730             self.writebytes(rEP0FIFO,ddata);
731             self.wregAS(rEP0BC,sendlen);
732         else:
733             print "Stalling in send_descriptor() for lack of handler for %02x." % desctype;
734             self.STALL_EP0();
735     def set_configuration(self,SUD):
736         """Set the configuration."""
737         bmSUSPIE=0x10;
738         configval=ord(SUD[wValueL]);
739         if(configval>0):
740             self.SETBIT(rUSBIEN,bmSUSPIE);
741         self.rregAS(rFNADDR);
742     def get_status(self,SUD):
743         """Get the USB Setup Status."""
744         testbyte=ord(SUD[bmRequestType])
745         
746         #Toward Device
747         if testbyte==0x80:
748             self.wreg(rEP0FIFO,0x03); #Enable RWU and self-powered
749             self.wreg(rEP0FIFO,0x00); #Second byte is always zero.
750             self.wregAS(rEP0BC,2);    #Load byte count, arm transfer, and ack CTL.
751         #Toward Interface
752         elif testbyte==0x81:
753             self.wreg(rEP0FIFO,0x00);
754             self.wreg(rEP0FIFO,0x00); #Second byte is always zero.
755             self.wregAS(rEP0BC,2);
756         #Toward Endpoint
757         elif testbyte==0x82:
758             if(ord(SUD[wIndexL])==0x83):
759                 self.wreg(rEP0FIFO,0x01); #Stall EP3
760                 self.wreg(rEP0FIFO,0x00); #Second byte is always zero.
761                 self.wregAS(rEP0BC,2);
762             else:
763                 self.STALL_EP0();
764         else:
765             self.STALL_EP0();
766     def service_irqs(self):
767         """Handle USB interrupt events."""
768         
769         epirq=self.rreg(rEPIRQ);
770         usbirq=self.rreg(rUSBIRQ);
771         
772         #Are we being asked for setup data?
773         if(epirq&bmSUDAVIRQ): #Setup Data Requested
774             self.wreg(rEPIRQ,bmSUDAVIRQ); #Clear the bit
775             self.do_SETUP();
776         if(epirq&bmIN3BAVIRQ): #EN3-IN packet
777             self.do_IN3();
778         
779     
780     typephase=0;
781     typestring="                      Python does USB HID!";
782     typepos=0;
783     
784     def asc2hid(self,ascii):
785         """Translate ASCII to an USB keycode."""
786         a=ascii;
787         if a>='a' and a<='z':
788             return ord(a)-ord('a')+4;
789         elif a>='A' and a<='Z':
790             return ord(a)-ord('A')+4;
791         elif a==' ':
792             return 0x2C; #space
793         else:
794             return 0; #key-up
795     def type_IN3(self):
796         """Type next letter in buffer."""
797         if self.typepos>=len(self.typestring):
798             self.typeletter(0);
799         elif self.typephase==0:
800             self.typephase=1;
801             self.typeletter(0);
802         else:
803             typephase=0;
804             self.typeletter(self.typestring[self.typepos]);
805             self.typepos=self.typepos+1;
806         return;
807     def typeletter(self,key):
808         """Type a letter on IN3.  Zero for keyup."""
809         #if type(key)==str: key=ord(key);
810         #Send a key-up.
811         self.wreg(rEP3INFIFO,0);
812         self.wreg(rEP3INFIFO,0);
813         self.wreg(rEP3INFIFO,self.asc2hid(key));
814         self.wreg(rEP3INBC,3);
815     def do_IN3(self):
816         """Handle IN3 event."""
817         #Don't bother clearing interrupt flag, that's done by sending the reply.
818         self.type_IN3();
819