import sys;
import binascii;
import array;
+import time;
from GoodFETMAXUSB import *;
-class GoodFETMAXUSBFTDI(GoodFETMAXUSB):
+class GoodFETMAXUSBFTDI(GoodFETMAXUSBDevice):
"""This emulates the FTDI USB to Serial chips."""
def hidinit(self):
"""Initialize a USB FTDI device."""
self.usb_disconnect();
+ time.sleep(1);
self.usb_connect();
- self.hidrun();
+ self.ftdirun();
- def hidrun(self):
+ def ftdirun(self):
"""Main loop of the USB FTDI emulator."""
print "Starting a FTDI device. This won't return.";
while 1:
self.service_irqs();
+ #self.typeletter_empty();
def do_SETUP(self):
"""Handle USB Enumeration"""
print "Bullshitting a value for the latency timer."
#Send some sort of reply.
self.wreg(rEP0FIFO,0x01);
- self.wreg(rEP0FIFO,0x00);
- self.wregAS(rEP0BC,2);
+ #self.wreg(rEP0FIFO,0x00);
+ self.wregAS(rEP0BC,1);
#Don't send reply twice.
return;
- print "Blindly accepting vendor request";
- #self.wreg(rEP0FIFO,0);
+ print "Blindly accepting unhandled vendor request %02x" % request;
self.wregAS(rEP0BC,0);
def std_request(self,SUD):
"""Handles a standard setup request."""
#Device Descriptor
DD=[0x12, # bLength = 18d
0x01, # bDescriptorType = Device (1)
- 0x00,0x01, # bcdUSB(L/H) USB spec rev (BCD)
+ 0x10,0x01, # bcdUSB(L/H) USB spec rev (BCD)
0x00,0x00,0x00, # bDeviceClass, bDeviceSubClass, bDeviceProtocol
0x40, # bMaxPacketSize0 EP0 is 64 bytes
0x03,0x04, # idVendor(L/H)--FTDI is 0403
- 0x01,0x60, # idProduct(L/H)--6001
- 0x34,0x12, # bcdDevice--1234
+ 0x72,0x83, # idProduct(L/H)--6001
+ 0x01,0x00, # bcdDevice--1234
1,2,3, # iManufacturer, iProduct, iSerialNumber
- 1];
+ 1 # One configuration.
+ ];
#Configuration Descriptor
CD=[0x09, # bLength
0x02, # bDescriptorType = Config
0xFF, # bInterfaceClass = FF=vendor
0xFF,0xFF, # bInterfaceSubClass, bInterfaceProtocol
0x02, # iInterface
-# HID Descriptor--It's at CD[18]
- # 0x09, # bLength
- # 0x21, # bDescriptorType = HID
- # 0x10,0x01, # bcdHID(L/H) Rev 1.1
- # 0x00, # bCountryCode (none)
- # 0x01, # bNumDescriptors (one report descriptor)
- # 0x22, # bDescriptorType (report)
- # 43,0, # CD[25]: wDescriptorLength(L/H) (report descriptor size is 43 bytes)
-# Endpoint Descriptor
+# IN Endpoint Descriptor
0x07, # bLength
0x05, # bDescriptorType (Endpoint)
0x83, # bEndpointAddress (EP3-IN)
- 0x02, # bmAttributes (interrupt)
+ 0x02, # bmAttributes (bulk)
64,0, # wMaxPacketSize (64)
- 10,
-# Endpoint Descriptor
+ 00,
+# OUT Endpoint Descriptor
0x07, # bLength
0x05, # bDescriptorType (Endpoint)
0x01, # bEndpointAddress (EP1-OUT)
- 0x02, # bmAttributes (interrupt)
+ 0x02, # bmAttributes (bulk)
64,0, # wMaxPacketSize (64)
- 10];
+ 00];
strDesc=[
# STRING descriptor 0--Language string
"\x04\x03\x09\x04",
# 0x09,0x04 # wLANGID(L/H) = English-United Sates
# ],
# STRING descriptor 1--Manufacturer ID
-"\x0c\x03M\x00a\x00x\x00i\x00m\x00",
-# [
-# 12, # bLength
-# 0x03, # bDescriptorType = string
-# 'M',0,'a',0,'x',0,'i',0,'m',0 # text in Unicode
-# ],
+"\x10\x03G\x00o\x00o\x00d\x00F\x00E\x00T\x00",
# STRING descriptor 2 - Product ID
-"\x18\x03M\x00A\x00X\x003\x004\x002\x000\x00E\x00 \x00E\x00n\x00u\x00m\x00 \x00C\x00o\x00d\x00e\x00",
-# [ 24, # bLength
-# 0x03, # bDescriptorType = string
-# 'M',0,'A',0,'X',0,'3',0,'4',0,'2',0,'0',0,'E',0,' ',0,
-# 'E',0,'n',0,'u',0,'m',0,' ',0,'C',0,'o',0,'d',0,'e',0
-# ],
-
-
+"\x18\x03F\x00T\x00D\x00I\x00 \x00E\x00m\x00u\x00l\x00a\x00t\x00o\x00r\x00 \x00 \x00 \x00 \x00 \x00",
# STRING descriptor 3 - Serial Number ID
"\x14\x03S\x00/\x00N\x00 \x003\x004\x002\x000\x00E\x00"
-# [ 20, # bLength
-# 0x03, # bDescriptorType = string
-# 'S',0,
-# '/',0,
-# 'N',0,
-# ' ',0,
-# '3',0,
-# '4',0,
-# '2',0,
-# '0',0,
-# 'E',0,
-# ]
];
- RepD=[
- 0x05,0x01, # Usage Page (generic desktop)
- 0x09,0x06, # Usage (keyboard)
- 0xA1,0x01, # Collection
- 0x05,0x07, # Usage Page 7 (keyboard/keypad)
- 0x19,0xE0, # Usage Minimum = 224
- 0x29,0xE7, # Usage Maximum = 231
- 0x15,0x00, # Logical Minimum = 0
- 0x25,0x01, # Logical Maximum = 1
- 0x75,0x01, # Report Size = 1
- 0x95,0x08, # Report Count = 8
- 0x81,0x02, # Input(Data,Variable,Absolute)
- 0x95,0x01, # Report Count = 1
- 0x75,0x08, # Report Size = 8
- 0x81,0x01, # Input(Constant)
- 0x19,0x00, # Usage Minimum = 0
- 0x29,0x65, # Usage Maximum = 101
- 0x15,0x00, # Logical Minimum = 0,
- 0x25,0x65, # Logical Maximum = 101
- 0x75,0x08, # Report Size = 8
- 0x95,0x01, # Report Count = 1
- 0x81,0x00, # Input(Data,Variable,Array)
- 0xC0]
- def send_descriptor(self,SUD):
- """Send the USB descriptors based upon the setup data."""
- desclen=0;
- reqlen=ord(SUD[wLengthL])+256*ord(SUD[wLengthH]); #16-bit length
- desctype=ord(SUD[wValueH]);
-
- if desctype==GD_DEVICE:
- desclen=self.DD[0];
- ddata=self.DD;
- elif desctype==GD_CONFIGURATION:
- desclen=self.CD[2];
- ddata=self.CD;
- elif desctype==GD_STRING:
- desclen=self.strDesc[ord(SUD[wValueL])][0];
- ddata=self.strDesc[ord(SUD[wValueL])];
- elif desctype==GD_REPORT:
- desclen=self.CD[25];
- ddata=self.RepD;
-
- #TODO Configuration, String, Hid, and Report
-
- if desclen>0:
- sendlen=min(reqlen,desclen);
- self.writebytes(rEP0FIFO,ddata);
- self.wregAS(rEP0BC,sendlen);
- else:
- print "Stalling in send_descriptor() for lack of handler for %02x." % desctype;
- self.STALL_EP0(SUD);
+
+
def set_configuration(self,SUD):
"""Set the configuration."""
bmSUSPIE=0x10;
self.do_SETUP();
elif(epirq&bmIN3BAVIRQ): #EN3-IN packet
self.do_IN3();
+ #self.wreg(rEPIRQ,bmIN3BAVIRQ); #Clear the bit
elif(epirq&bmOUT1DAVIRQ): #OUT1-OUT packet
- self.wreg(rEPIRQ,bmOUT1DAVIRQ); #Clear the bit
self.do_OUT1();
-
-
+ self.wregAS(rEPIRQ,bmOUT1DAVIRQ); #Clear the bit *AFTER* servicing.
+ #else:
+ # self.do_IN3();
- typephase=0;
- typestring=" GoodFET emulating FTDI!";
+ typestring="GoodFET emulates FTDI properly, if you can read this!\n";
typepos=0;
- def asc2hid(self,ascii):
- """Translate ASCII to an USB keycode."""
- a=ascii;
- if a>='a' and a<='z':
- return ord(a)-ord('a')+4;
- elif a>='A' and a<='Z':
- return ord(a)-ord('A')+4;
- elif a==' ':
- return 0x2C; #space
- else:
- return 0; #key-up
def type_IN3(self):
"""Type next letter in buffer."""
if self.typepos>=len(self.typestring):
- self.typeletter(0);
- elif self.typephase==0:
- self.typephase=1;
- self.typeletter(0);
+ self.typepos=0;
+ self.typeletter(' ');
else:
- typephase=0;
self.typeletter(self.typestring[self.typepos]);
self.typepos=self.typepos+1;
return;
def typeletter(self,key):
"""Type a letter on IN3. Zero for keyup."""
- #if type(key)==str: key=ord(key);
- #Send a key-up.
- self.wreg(rEP3INFIFO,0);
- self.wreg(rEP3INFIFO,0);
- self.wreg(rEP3INFIFO,self.asc2hid(key));
- self.wreg(rEP3INBC,3);
+ if type(key)==str: key=ord(key);
+
+ self.wreg(rEP3INFIFO,0x01); #Modem Status
+ self.wreg(rEP3INFIFO,0x00); #Line Status
+ self.wreg(rEP3INFIFO,key);
+ self.wregAS(rEP3INBC,3);
def do_IN3(self):
"""Handle IN3 input event."""
#Don't bother clearing interrupt flag, that's done by sending the reply.
- #print "Got an input event, sending back some garbage that might be right.";
self.type_IN3();
def do_OUT1(self):
"""Handle an OUT1 output event."""
print "Got an output event, printing the result.";
- frame=self.readbytes(rEP1OUTFIFO,64);
- #print "Got %s" % frame;
+ l=self.rreg(rEP1OUTBC);
+ frame=self.readbytesAS(rEP1OUTFIFO,l);
+ print "FTDI OUT: %s" % frame[1:len(frame)];
+ #self.type_IN3();
#Initialize FET and set baud rate
client=GoodFETMAXUSBFTDI();