2 # GoodFET Client Library for Maxim USB Chips.
4 # (C) 2012 Travis Goodspeed <travis at radiantmachines.com>
6 # This code is being rewritten and refactored. You've been warned!
9 import sys, time, string, cStringIO, struct, glob, os;
12 from GoodFET import GoodFET;
15 """This library will soon be deprecated in favor of the USB*.py libraries."""
40 rIOPINS1=20 #Same as rIOPINS
58 # R11 EPIRQ register bits
66 # R12 EPIEN register bits
77 # ************************
78 # Standard USB Requests
79 SR_GET_STATUS =0x00 # Get Status
80 SR_CLEAR_FEATURE =0x01 # Clear Feature
81 SR_RESERVED =0x02 # Reserved
82 SR_SET_FEATURE =0x03 # Set Feature
83 SR_SET_ADDRESS =0x05 # Set Address
84 SR_GET_DESCRIPTOR =0x06 # Get Descriptor
85 SR_SET_DESCRIPTOR =0x07 # Set Descriptor
86 SR_GET_CONFIGURATION =0x08 # Get Configuration
87 SR_SET_CONFIGURATION =0x09 # Set Configuration
88 SR_GET_INTERFACE =0x0a # Get Interface
89 SR_SET_INTERFACE =0x0b # Set Interface
91 # Get Descriptor codes
92 GD_DEVICE =0x01 # Get device descriptor: Device
93 GD_CONFIGURATION =0x02 # Get device descriptor: Configuration
94 GD_STRING =0x03 # Get device descriptor: String
95 GD_HID =0x21 # Get descriptor: HID
96 GD_REPORT =0x22 # Get descriptor: Report
98 # SETUP packet header offsets
108 # HID bRequest values
166 # Host XFR token values for writing the HXFR register (R30).
167 # OR this bit field with the endpoint number in bits 3:0
168 tokSETUP =0x10 # HS=0, ISO=0, OUTNIN=0, SETUP=1
169 tokIN =0x00 # HS=0, ISO=0, OUTNIN=0, SETUP=0
170 tokOUT =0x20 # HS=0, ISO=0, OUTNIN=1, SETUP=0
171 tokINHS =0x80 # HS=1, ISO=0, OUTNIN=0, SETUP=0
172 tokOUTHS =0xA0 # HS=1, ISO=0, OUTNIN=1, SETUP=0
173 tokISOIN =0x40 # HS=0, ISO=1, OUTNIN=0, SETUP=0
174 tokISOOUT =0x60 # HS=0, ISO=1, OUTNIN=1, SETUP=0
181 # Host error result codes, the 4 LSB's in the HRSL register.
200 bmBUSEVENTIRQ =0x01 # indicates BUS Reset Done or BUS Resume
209 class GoodFETMAXUSB(GoodFET):
213 def service_irqs(self):
214 """Handle USB interrupt events."""
215 epirq=self.rreg(rEPIRQ);
216 usbirq=self.rreg(rUSBIRQ);
219 #Are we being asked for setup data?
220 if(epirq&bmSUDAVIRQ): #Setup Data Requested
221 self.wreg(rEPIRQ,bmSUDAVIRQ); #Clear the bit
223 if(epirq&bmOUT1DAVIRQ): #OUT1-OUT packet
225 self.wreg(rEPIRQ,bmOUT1DAVIRQ); #Clear the bit *AFTER* servicing.
226 if(epirq&bmIN3BAVIRQ): #IN3-IN packet
228 #self.wreg(rEPIRQ,bmIN3BAVIRQ); #Clear the bit
229 if(epirq&bmIN2BAVIRQ): #IN2 packet
231 #self.wreg(rEPIRQ,bmIN2BAVIRQ); #Clear the bit
233 # print "No idea how to service this IRQ: %02x" % epirq;
240 if self.usbverbose: print "Ignoring an OUT1 interrupt.";
241 def setup2str(self,SUD):
242 """Converts the header of a setup packet to a string."""
243 return "bmRequestType=0x%02x, bRequest=0x%02x, wValue=0x%04x, wIndex=0x%04x, wLength=0x%04x" % (
244 ord(SUD[0]), ord(SUD[1]),
245 ord(SUD[2])+(ord(SUD[3])<<8),
246 ord(SUD[4])+(ord(SUD[5])<<8),
247 ord(SUD[6])+(ord(SUD[7])<<8)
250 def MAXUSBsetup(self):
251 """Move the FET into the MAXUSB application."""
252 self.writecmd(self.MAXUSBAPP,0x10,0,self.data); #MAXUSB/SETUP
253 self.writecmd(self.MAXUSBAPP,0x10,0,self.data); #MAXUSB/SETUP
254 self.writecmd(self.MAXUSBAPP,0x10,0,self.data); #MAXUSB/SETUP
255 print "Connected to MAX342x Rev. %x" % (self.rreg(rREVISION));
256 self.wreg(rPINCTL,0x18); #Set duplex and negative INT level.
258 def MAXUSBtrans8(self,byte):
259 """Read and write 8 bits by MAXUSB."""
260 data=self.MAXUSBtrans([byte]);
263 def MAXUSBtrans(self,data):
264 """Exchange data by MAXUSB."""
266 self.writecmd(self.MAXUSBAPP,0x00,len(data),data);
270 """Peek 8 bits from a register."""
272 self.writecmd(self.MAXUSBAPP,0x00,len(data),data);
273 return ord(self.data[1]);
274 def rregAS(self,reg):
275 """Peek 8 bits from a register, setting AS."""
277 self.writecmd(self.MAXUSBAPP,0x00,len(data),data);
278 return ord(self.data[1]);
279 def wreg(self,reg,value):
280 """Poke 8 bits into a register."""
281 data=[(reg<<3)|2,value];
282 self.writecmd(self.MAXUSBAPP,0x00,len(data),data);
284 def wregAS(self,reg,value):
285 """Poke 8 bits into a register, setting AS."""
286 data=[(reg<<3)|3,value];
287 self.writecmd(self.MAXUSBAPP,0x00,len(data),data);
289 def readbytes(self,reg,length):
290 """Peek some bytes from a register."""
291 data=[(reg<<3)]+range(0,length);
292 self.writecmd(self.MAXUSBAPP,0x00,len(data),data);
293 toret=self.data[1:len(self.data)];
296 ashex=ashex+(" %02x"%ord(foo));
297 if self.usbverbose: print "GET %02x==%s" % (reg,ashex);
299 def readbytesAS(self,reg,length):
300 """Peek some bytes from a register, acking prior transfer."""
301 data=[(reg<<3)|1]+range(0,length);
302 self.writecmd(self.MAXUSBAPP,0x00,len(data),data);
303 toret=self.data[1:len(self.data)];
306 ashex=ashex+(" %02x"%ord(foo));
307 if self.usbverbose: print "GETAS %02x==%s" % (reg,ashex);
309 def fifo_ep3in_tx(self,data):
310 """Sends the data out of EP3 in 64-byte chunks."""
311 #Wait for the buffer to be free before starting.
312 while not(self.rreg(rEPIRQ)&bmIN3BAVIRQ): pass;
317 #Send 64-byte chunks or the remainder.
319 self.writebytes(rEP3INFIFO,
321 self.wregAS(rEP3INBC,c);
325 #Wait for the buffer to be free before continuing.
326 while not(self.rreg(rEPIRQ)&bmIN3BAVIRQ): pass;
330 def ctl_write_nd(self,request):
331 """Control Write with no data stage. Assumes PERADDR is set
332 and the SUDFIFO contains the 8 setup bytes. Returns with
333 result code = HRSLT[3:0] (HRSL register). If there is an
334 error, the 4MSBits of the returned value indicate the stage 1
337 # 1. Send the SETUP token and 8 setup bytes.
338 # Should ACK immediately.
339 self.writebytes(rSUDFIFO,request);
340 resultcode=self.send_packet(tokSETUP,0); #SETUP packet to EP0.
341 if resultcode: return resultcode;
343 # 2. No data stage, so the last operation is to send an IN
344 # token to the peripheral as the STATUS (handhsake) stage of
345 # this control transfer. We should get NAK or the DATA1 PID.
346 # When we get back to the DATA1 PID the 3421 automatically
347 # sends the closing NAK.
348 resultcode=self.send_packet(tokINHS,0); #Function takes care of retries.
349 if resultcode: return resultcode;
354 def ctl_read(self,request):
355 """Control read transfer, used in Host mode."""
357 bytes_to_read=request[6]+256*request[7];
360 self.writebytes(rSUDFIFO,request); #Load the FIFO
361 resultcode=self.send_packet(tokSETUP,0); #SETUP packet to EP0
363 print "Failed to get ACK on SETUP request in ctl_read()."
366 self.wreg(rHCTL,bmRCVTOG1); #FIRST data packet in CTL transfer uses DATA1 toggle.
367 resultcode=self.IN_Transfer(0,bytes_to_read);
369 print "Failed on IN Transfer in ctl_read()";
372 self.IN_nak_count=self.nak_count;
374 #The OUT status stage.
375 resultcode=self.send_packet(tokOUTHS,0);
377 print "Failed on OUT Status stage in ctl_read()";
382 xfrdata=[]; #Ugly variable used only by a few functions. FIXME
383 def IN_Transfer(self,endpoint,INbytes):
384 """Does an IN transfer to an endpoint, used for Host mode."""
390 resultcode=self.send_packet(tokIN,endpoint); #IN packet to EP. NAKS taken care of.
391 if resultcode: return resultcode;
393 pktsize=self.rreg(rRCVBC); #Numer of RXed bytes.
395 #Very innefficient, move this to C if performance is needed.
396 for j in range(0,pktsize):
397 self.xfrdata=self.xfrdata+[self.rreg(rRCVFIFO)];
398 xfrsize=self.xfrdata[0];
399 self.wreg(rHIRQ,bmRCVDAVIRQ); #Clear IRQ
400 xfrlen=xfrlen+pktsize; #Add byte count to total transfer length.
402 #print "%i / %i" % (xfrlen,xfrsize)
404 #Packet is complete if:
405 # 1. The device sent a short packet, <maxPacketSize
406 # 2. INbytes have been transfered.
407 if (pktsize<self.maxPacketSize) or (xfrlen>=xfrsize):
408 self.last_transfer_size=xfrlen;
410 for foo in self.xfrdata:
411 ashex=ashex+(" %02x"%foo);
412 #print "INPACKET EP%i==%s (0x%02x bytes remain)" % (endpoint,ashex,xfrsize);
417 def send_packet(self,token,endpoint):
418 """Send a packet to an endpoint as the Host, taking care of NAKs.
419 Don't use this for device code."""
423 #Repeat until NAK_LIMIT or RETRY_LIMIT is reached.
424 while self.nak_count<self.NAK_LIMIT and self.retry_count<self.RETRY_LIMIT:
425 self.wreg(rHXFR,(token|endpoint)); #launch the transfer
426 while not (self.rreg(rHIRQ) & bmHXFRDNIRQ):
427 # wait for the completion IRQ
429 self.wreg(rHIRQ,bmHXFRDNIRQ); #Clear IRQ
430 resultcode = (self.rreg(rHRSL) & 0x0F); # get the result
431 if (resultcode==hrNAK):
432 self.nak_count=self.nak_count+1;
433 elif (resultcode==hrTIMEOUT):
434 self.retry_count=self.retry_count+1;
440 def writebytes(self,reg,tosend):
441 """Poke some bytes into a register."""
443 if type(tosend)==str:
444 data=chr((reg<<3)|3)+tosend;
445 if self.usbverbose: print "PUT %02x:=%s (0x%02x bytes)" % (reg,tosend,len(data))
447 data=[(reg<<3)|3]+tosend;
450 ashex=ashex+(" %02x"%foo);
451 if self.usbverbose: print "PUT %02x:=%s (0x%02x bytes)" % (reg,ashex,len(data))
452 self.writecmd(self.MAXUSBAPP,0x00,len(data),data);
453 def usb_connect(self):
454 """Connect the USB port."""
456 #disconnect D+ pullup if host turns off VBUS
457 self.wreg(rUSBCTL,bmVBGATE|bmCONNECT);
458 def usb_disconnect(self):
459 """Disconnect the USB port."""
460 self.wreg(rUSBCTL,bmVBGATE);
461 def STALL_EP0(self,SUD=None):
462 """Stall for an unknown SETUP event."""
464 print "Stalling EP0.";
466 print "Stalling EPO for %s" % self.setup2str(SUD);
467 self.wreg(rEPSTALLS,0x23); #All three stall bits.
468 def SETBIT(self,reg,val):
469 """Set a bit in a register."""
470 self.wreg(reg,self.rreg(reg)|val);
472 """Turn on the target device."""
473 self.wreg(rIOPINS2,(self.rreg(rIOPINS2)|0x08));
475 """Turn off the target device's power."""
476 self.wreg(rIOPINS2,0x00);
477 def reset_host(self):
478 """Resets the chip into host mode."""
479 self.wreg(rUSBCTL,bmCHIPRES); #Stop the oscillator.
480 self.wreg(rUSBCTL,0x00); #restart it.
482 #FIXME: Why does the OSC line never settle?
483 #Code works without it.
485 #print "Waiting for PLL to sabilize.";
486 #while self.rreg(rUSBIRQ)&bmOSCOKIRQ:
487 # #Hang until the PLL stabilizes.
491 class GoodFETMAXUSBHost(GoodFETMAXUSB):
492 """This is a class for implemented a minimal USB host.
493 It's intended for fuzzing, rather than for daily use."""
495 """Initialize the MAX3421 as a USB Host."""
497 print "Enabling host mode.";
498 self.wreg(rPINCTL,(bmFDUPSPI|bmPOSINT));
499 print "Resetting host.";
503 print "Powering host.";
508 """Run as a minimal host and dump the config tables."""
510 self.detect_device();
512 self.enumerate_device();
513 self.wait_for_disconnect();
514 def detect_device(self):
515 """Waits for a device to be inserted and then returns."""
518 #Activate host mode and turn on 15K pulldown resistors on D+ and D-.
519 self.wreg(rMODE,(bmDPPULLDN|bmDMPULLDN|bmHOST));
520 #Clear connection detect IRQ.
521 self.wreg(rHIRQ,bmCONDETIRQ);
523 print "Waiting for a device connection.";
525 self.wreg(rHCTL,bmSAMPLEBUS); #Update JSTATUS and KSTATUS bits.
526 busstate=self.rreg(rHRSL) & (bmJSTATUS|bmKSTATUS);
528 if busstate==bmJSTATUS:
529 print "Detected Full-Speed Device.";
530 self.wreg(rMODE,(bmDPPULLDN|bmDMPULLDN|bmHOST|bmSOFKAENAB));
531 elif busstate==bmKSTATUS:
532 print "Detected Low-Speed Device.";
533 self.wreg(rMODE,(bmDPPULLDN|bmDMPULLDN|bmHOST|bmLOWSPEED|bmSOFKAENAB));
535 print "Not sure whether this is Full-Speed or Low-Speed. Please investigate.";
536 def wait_for_disconnect(self):
537 """Wait for a device to be disconnected."""
538 print "Waiting for a device disconnect.";
540 self.wreg(rHIRQ,bmCONDETIRQ); #Clear disconnect IRQ
541 while not (self.rreg(rHIRQ) & bmCONDETIRQ):
542 #Wait for IRQ to change.
546 self.wreg(rMODE,bmDPPULLDN|bmDMPULLDN|bmHOST);
547 print "Device disconnected.";
548 self.wreg(rIOPINS2,(self.rreg(rIOPINS2) & ~0x04)); #HL1_OFF
549 self.wreg(rIOPINS1,(self.rreg(rIOPINS1) & ~0x02)); #HL4_OFF
551 def enumerate_device(self):
552 """Enumerates a device on the present port."""
554 Set_Address_to_7 = [0x00,0x05,0x07,0x00,0x00,0x00,0x00,0x00];
555 Get_Descriptor_Device = [0x80,0x06,0x00,0x01,0x00,0x00,0x00,0x00]; #len filled in
556 Get_Descriptor_Config = [0x80,0x06,0x00,0x02,0x00,0x00,0x00,0x00];
559 print "Issuing USB bus reset.";
560 self.wreg(rHCTL,bmBUSRST);
561 while self.rreg(rHCTL) & bmBUSRST:
562 #Wait for reset to complete.
567 #Get the device descriptor.
568 self.wreg(rPERADDR,0); #First request to address 0.
569 self.maxPacketSize=8; #Only safe value for first check.
570 Get_Descriptor_Device[6]=8; # wLengthL
571 Get_Descriptor_Device[7]=0; # wLengthH
573 print "Fetching 8 bytes of Device Descriptor.";
574 self.ctl_read(Get_Descriptor_Device); # Get device descriptor into self.xfrdata;
575 self.maxPacketSize=self.xfrdata[7];
576 print "EP0 maxPacketSize is %02i bytes." % self.maxPacketSize;
578 # Issue another USB bus reset
579 print "Resetting the bus again."
580 self.wreg(rHCTL,bmBUSRST);
581 while self.rreg(rHCTL) & bmBUSRST:
582 #Wait for reset to complete.
586 # Set_Address to 7 (Note: this request goes to address 0, already set in PERADDR register).
587 print "Setting address to 0x07";
588 HR = self.ctl_write_nd(Set_Address_to_7); # CTL-Write, no data stage
589 #if(print_error(HR)) return;
591 time.sleep(0.002); # Device gets 2 msec recovery time
592 self.wreg(rPERADDR,7); # now all transfers go to addr 7
595 #Get the device descriptor at the assigned address.
596 Get_Descriptor_Device[6]=0x12; #Fill in real descriptor length.
597 print "Fetching Device Descriptor."
598 self.ctl_read(Get_Descriptor_Device); #Result in self.xfrdata;
600 self.descriptor=self.xfrdata;
601 self.VID = self.xfrdata[8] + 256*self.xfrdata[9];
602 self.PID = self.xfrdata[10]+ 256*self.xfrdata[11];
603 iMFG = self.xfrdata[14];
604 iPROD = self.xfrdata[15];
605 iSERIAL = self.xfrdata[16];
607 self.manufacturer=self.getDescriptorString(iMFG);
608 self.product=self.getDescriptorString(iPROD);
609 self.serial=self.getDescriptorString(iSERIAL);
613 def printstrings(self):
614 print "Vendor ID is %04x." % self.VID;
615 print "Product ID is %04x." % self.PID;
616 print "Manufacturer: %s" % self.manufacturer;
617 print "Product: %s" % self.product;
618 print "Serial: %s" % self.serial;
620 def getDescriptorString(self, index):
621 """Grabs a string from the descriptor string table."""
622 # Get_Descriptor-String template. Code fills in idx at str[2].
623 Get_Descriptor_String = [0x80,0x06,index,0x03,0x00,0x00,0x40,0x00];
625 if index==0: return "MISSING STRING";
627 status=self.ctl_read(Get_Descriptor_String);
628 if status: return None;
630 #Since we've got a string
632 for c in self.xfrdata[2:len(self.xfrdata)]:
633 if c>0: toret=toret+chr(c);
635 class GoodFETMAXUSBDevice(GoodFETMAXUSB):
637 def send_descriptor(self,SUD):
638 """Send the USB descriptors based upon the setup data."""
640 reqlen=ord(SUD[wLengthL])+256*ord(SUD[wLengthH]); #16-bit length
641 desctype=ord(SUD[wValueH]);
643 if desctype==GD_DEVICE:
646 elif desctype==GD_CONFIGURATION:
649 elif desctype==GD_STRING:
650 desclen=ord(self.strDesc[ord(SUD[wValueL])][0]);
651 ddata=self.strDesc[ord(SUD[wValueL])];
652 elif desctype==GD_HID:
653 #Don't know how to do this yet.
655 elif desctype==GD_REPORT:
658 #TODO Configuration, String, Hid, and Report
661 #Reduce desclen if asked for fewer bytes.
662 desclen=min(reqlen,desclen);
664 self.writebytes(rEP0FIFO,ddata[0:desclen]);
665 self.wregAS(rEP0BC,desclen);
667 print "Stalling in send_descriptor() for lack of handler for %02x." % desctype;
669 def set_configuration(self,SUD):
670 """Set the configuration."""
672 configval=ord(SUD[wValueL]);
674 self.SETBIT(rUSBIEN,bmSUSPIE);
675 self.rregAS(rFNADDR);
676 class GoodFETMAXUSBHID(GoodFETMAXUSBDevice):
677 """This is an example HID keyboard driver, loosely based on the
680 """Initialize a USB HID device."""
681 self.usb_disconnect();
687 """Main loop of the USB HID emulator."""
688 print "Starting a HID device. This won't return.";
692 """Handle USB Enumeration"""
694 #Grab the SETUP packet from the buffer.
695 SUD=self.readbytes(rSUDFIFO,8);
697 #Parse the SETUP packet
698 print "Handling a setup packet of %s" % self.setup2str(SUD);
700 self.OsLastConfigType=ord(SUD[bmRequestType]);
702 setuptype=(ord(SUD[bmRequestType])&0x60);
704 self.std_request(SUD);
705 elif setuptype==0x20:
706 self.class_request(SUD);
707 elif setuptype==0x40:
708 self.vendor_request(SUD);
710 print "Unknown request type 0x%02x." % ord(SUD[bmRequestType])
712 def class_request(self,SUD):
713 """Handle a class request."""
714 print "Stalling a class request.";
716 def vendor_request(self,SUD):
717 print "Stalling a vendor request.";
719 def std_request(self,SUD):
720 """Handles a standard setup request."""
721 setuptype=ord(SUD[bRequest]);
722 if setuptype==SR_GET_DESCRIPTOR: self.send_descriptor(SUD);
723 #elif setuptype==SR_SET_FEATURE:
724 # self.rregAS(rFNADDR);
726 elif setuptype==SR_SET_CONFIGURATION: self.set_configuration(SUD);
727 elif setuptype==SR_GET_STATUS: self.get_status(SUD);
728 elif setuptype==SR_SET_ADDRESS: self.rregAS(rFNADDR);
729 elif setuptype==SR_GET_INTERFACE: self.get_interface(SUD);
731 print "Stalling Unknown standard setup request type %02x" % setuptype;
734 def get_interface(self,SUD):
735 """Handles a setup request for SR_GET_INTERFACE."""
736 if ord(SUD[wIndexL]==0):
737 self.wreg(rEP0FIFO,0);
738 self.wregAS(rEP0BC,1);
744 DD=[0x12, # bLength = 18d
745 0x01, # bDescriptorType = Device (1)
746 0x00,0x01, # bcdUSB(L/H) USB spec rev (BCD)
747 0x00,0x00,0x00, # bDeviceClass, bDeviceSubClass, bDeviceProtocol
748 0x40, # bMaxPacketSize0 EP0 is 64 bytes
749 0x6A,0x0B, # idVendor(L/H)--Maxim is 0B6A
750 0x46,0x53, # idProduct(L/H)--5346
751 0x34,0x12, # bcdDevice--1234
752 1,2,3, # iManufacturer, iProduct, iSerialNumber
754 #Configuration Descriptor
756 0x02, # bDescriptorType = Config
757 0x22,0x00, # wTotalLength(L/H) = 34 bytes
758 0x01, # bNumInterfaces
760 0x00, # iConfiguration
761 0xE0, # bmAttributes. b7=1 b6=self-powered b5=RWU supported
762 0x01, # MaxPower is 2 ma
763 # INTERFACE Descriptor
767 0x00, # bAlternate Setting
768 0x01, # bNum Endpoints
769 0x03, # bInterfaceClass = HID
770 0x00,0x00, # bInterfaceSubClass, bInterfaceProtocol
772 # HID Descriptor--It's at CD[18]
774 0x21, # bDescriptorType = HID
775 0x10,0x01, # bcdHID(L/H) Rev 1.1
776 0x00, # bCountryCode (none)
777 0x01, # bNumDescriptors (one report descriptor)
778 0x22, # bDescriptorType (report)
779 43,0, # CD[25]: wDescriptorLength(L/H) (report descriptor size is 43 bytes)
780 # Endpoint Descriptor
782 0x05, # bDescriptorType (Endpoint)
783 0x83, # bEndpointAddress (EP3-IN)
784 0x03, # bmAttributes (interrupt)
785 64,0, # wMaxPacketSize (64)
788 # STRING descriptor 0--Language string
792 # 0x03, # bDescriptorType = string
793 # 0x09,0x04 # wLANGID(L/H) = English-United Sates
795 # STRING descriptor 1--Manufacturer ID
796 "\x0c\x03M\x00a\x00x\x00i\x00m\x00",
799 # 0x03, # bDescriptorType = string
800 # 'M',0,'a',0,'x',0,'i',0,'m',0 # text in Unicode
802 # STRING descriptor 2 - Product ID
803 "\x18\x03M\x00A\x00X\x003\x004\x002\x000\x00E\x00 \x00E\x00n\x00u\x00m\x00 \x00C\x00o\x00d\x00e\x00",
805 # 0x03, # bDescriptorType = string
806 # 'M',0,'A',0,'X',0,'3',0,'4',0,'2',0,'0',0,'E',0,' ',0,
807 # 'E',0,'n',0,'u',0,'m',0,' ',0,'C',0,'o',0,'d',0,'e',0
811 # STRING descriptor 3 - Serial Number ID
812 "\x14\x03S\x00/\x00N\x00 \x003\x004\x002\x000\x00E\x00"
814 # 0x03, # bDescriptorType = string
827 0x05,0x01, # Usage Page (generic desktop)
828 0x09,0x06, # Usage (keyboard)
829 0xA1,0x01, # Collection
830 0x05,0x07, # Usage Page 7 (keyboard/keypad)
831 0x19,0xE0, # Usage Minimum = 224
832 0x29,0xE7, # Usage Maximum = 231
833 0x15,0x00, # Logical Minimum = 0
834 0x25,0x01, # Logical Maximum = 1
835 0x75,0x01, # Report Size = 1
836 0x95,0x08, # Report Count = 8
837 0x81,0x02, # Input(Data,Variable,Absolute)
838 0x95,0x01, # Report Count = 1
839 0x75,0x08, # Report Size = 8
840 0x81,0x01, # Input(Constant)
841 0x19,0x00, # Usage Minimum = 0
842 0x29,0x65, # Usage Maximum = 101
843 0x15,0x00, # Logical Minimum = 0,
844 0x25,0x65, # Logical Maximum = 101
845 0x75,0x08, # Report Size = 8
846 0x95,0x01, # Report Count = 1
847 0x81,0x00, # Input(Data,Variable,Array)
850 def get_status(self,SUD):
851 """Get the USB Setup Status."""
852 testbyte=ord(SUD[bmRequestType])
856 self.wreg(rEP0FIFO,0x03); #Enable RWU and self-powered
857 self.wreg(rEP0FIFO,0x00); #Second byte is always zero.
858 self.wregAS(rEP0BC,2); #Load byte count, arm transfer, and ack CTL.
861 self.wreg(rEP0FIFO,0x00);
862 self.wreg(rEP0FIFO,0x00); #Second byte is always zero.
863 self.wregAS(rEP0BC,2);
866 if(ord(SUD[wIndexL])==0x83):
867 self.wreg(rEP0FIFO,0x01); #Stall EP3
868 self.wreg(rEP0FIFO,0x00); #Second byte is always zero.
869 self.wregAS(rEP0BC,2);
877 -1 : "Python does USB HID!\n", # Unidentified OS. This is the default typestring.
878 0x00 : "OSX Hosts don't recognize Maxim keyboards.\n", # We have to identify as an Apple keyboard to get arround the unknown keyboard error.
879 0xA1 : "Python does USB HID on Linux!\n",
880 0x81 : " Python does USB HID on Windows!\n", # Windows requires a bit of a delay. Maybe we can watch for a keyboard reset command?
882 def typestring(self):
883 if self.typestrings.has_key(self.OsLastConfigType):
884 return self.typestrings[self.OsLastConfigType];
886 return self.typestrings[-1];
887 # http://www.win.tue.nl/~aeb/linux/kbd/scancodes-14.html
888 # Escape=0x29 Backsp=0x2A Space=0x2C CapsLock=0x39 Menu=0x65
890 'en_US' :[ ' abcdefghijklmnopqrstuvwxyz1234567890\n
\e\7f\t -=[]\\\\;\'`,./',
891 '''
\ 1\ 2\ 3\ 4\ 5\ 6\a\b \v\f\r\ e\ f\10 \12 \14\15\16\17\18\19\1a''', # LeftCtrl
892 ' ABCDEFGHIJKLMNOPQRSTUVWXYZ!@#$%^&*() {}?+||:"~<>?', # LeftShift
893 '', # LeftCtrl & LeftShift
894 '
\ea
\eb
\ec'], # LeftAlt
895 'Dvorak' :[ ' axje.uidchtnmbrl\'poygk,qf;1234567890\n
\e\7f\t []/=\\\\s-`wvz',
896 '''
\ 1\18 \ 5 \15 \ 4\ 3\b\14\ e\r\ 2\12\f \10\ f\19\a\v \ 6 \17\16\1a''', # LeftCtrl
897 ' AXJE UIDCHTNMBRL"POYGK<QF:!@#$%^&*() {}?+||S_~WVZ', # LeftShift
898 '', # LeftCtrl & LeftShift
899 '
\ea
\ex
\ej'], # LeftAlt
903 return self.keymaps[self.layout];
906 'LeftCtrl': 0b00000001,
907 'LeftShift': 0b00000010,
908 'LeftAlt': 0b00000100,
909 'LeftGUI': 0b00001000,
910 'RightCtrl': 0b00010000,
911 'RightShift': 0b00100000,
912 'RightAlt': 0b01000000,
913 'RightGUI': 0b10000000
916 def asc2hid(self,ascii):
917 """Translate ASCII to an USB keycode."""
919 return (0,0); # Send NoEvent if not passed a character
921 return (0,0x2C); # space
922 for modset in self.keymap():
923 keycode=modset.find(ascii);
925 modifier = self.keymap().index(modset)
926 return (modifier, keycode);
929 """Type next letter in buffer."""
930 string=self.typestring();
931 if self.typepos>=len(string):
932 self.typeletter(0); # Send NoEvent to indicate key-up
934 self.typepos=0; # Repeat typestring forever!
935 # This would be a great place to enable a typethrough mode so the host operator can control the target
938 sys.stdout.write(string[self.typepos]);
940 self.typeletter(string[self.typepos]);
943 def typeletter(self,key):
944 """Type a letter on IN3. Zero for keyup."""
947 (mod, key) = self.asc2hid(key);
948 self.wreg(rEP3INFIFO,mod);
949 self.wreg(rEP3INFIFO,0);
950 self.wreg(rEP3INFIFO,key);
951 self.wreg(rEP3INBC,3);
953 """Handle IN3 event."""
954 #Don't bother clearing interrupt flag, that's done by sending the reply.
955 if self.OsLastConfigType != -1: # Wait for some configuration before stuffing keycodes down the pipe