FTDI emulation now works well for OUT.
[goodfet] / client / GoodFETMAXUSB.py
index 8f05d43..f16da04 100644 (file)
@@ -90,7 +90,7 @@ GD_STRING             =0x03   # Get device descriptor: String
 GD_HID                 =0x21   # Get descriptor: HID
 GD_REPORT              =0x22   # Get descriptor: Report
 
-# SETUP packet offsets
+# SETUP packet header offsets
 bmRequestType           =0
 bRequest                       =1
 wValueL                        =2
@@ -203,6 +203,16 @@ bmHXFRDNIRQ     =0x80
 
 class GoodFETMAXUSB(GoodFET):
     MAXUSBAPP=0x40;
+    
+    def setup2str(self,SUD):
+        """Converts the header of a setup packet to a string."""
+        return "bmRequestType=0x%02x, bRequest=0x%02x, wValue=0x%04x, wIndex=0x%04x, wLength=0x%04x" % (
+                ord(SUD[0]), ord(SUD[1]),
+                ord(SUD[2])+(ord(SUD[3])<<8),
+                ord(SUD[4])+(ord(SUD[5])<<8),
+                ord(SUD[6])+(ord(SUD[7])<<8)
+                );
+    
     def MAXUSBsetup(self):
         """Move the FET into the MAXUSB application."""
         self.writecmd(self.MAXUSBAPP,0x10,0,self.data); #MAXUSB/SETUP
@@ -318,9 +328,11 @@ class GoodFETMAXUSB(GoodFET):
             #Very innefficient, move this to C if performance is needed.
             for j in range(0,pktsize):
                 self.xfrdata=self.xfrdata+[self.rreg(rRCVFIFO)];
+            xfrsize=self.xfrdata[0];
             self.wreg(rHIRQ,bmRCVDAVIRQ); #Clear IRQ
             xfrlen=xfrlen+pktsize; #Add byte count to total transfer length.
             
+            print "%i / %i" % (xfrlen,xfrsize)
             
             #Packet is complete if:
             # 1. The device sent a short packet, <maxPacketSize
@@ -330,7 +342,7 @@ class GoodFETMAXUSB(GoodFET):
                 ashex="";
                 for foo in self.xfrdata:
                     ashex=ashex+(" %02x"%foo);
-                print "INPACKET EP%i==%s" % (endpoint,ashex);
+                print "INPACKET EP%i==%s (0x%02x bytes remain)" % (endpoint,ashex,xfrsize);
                 return resultcode;
 
     RETRY_LIMIT=3;
@@ -363,6 +375,7 @@ class GoodFETMAXUSB(GoodFET):
         data="";
         if type(tosend)==str:
             data=chr((reg<<3)|2)+tosend;
+            print "PUT %02x:=%s" % (reg,tosend)
         else:
             data=[(reg<<3)|2]+tosend;
             ashex="";
@@ -374,10 +387,16 @@ class GoodFETMAXUSB(GoodFET):
         """Connect the USB port."""
         
         #disconnect D+ pullup if host turns off VBUS
-        self.wreg(rUSBCTL,0x48);
-    def STALL_EP0(self):
-        """Stall for an unknown event."""
-        print "Stalling.";
+        self.wreg(rUSBCTL,bmVBGATE|bmCONNECT);
+    def usb_disconnect(self):
+        """Disconnect the USB port."""
+        self.wreg(rUSBCTL,bmVBGATE);
+    def STALL_EP0(self,SUD=None):
+        """Stall for an unknown SETUP event."""
+        if SUD==None:
+            print "Stalling EP0.";
+        else:
+            print "Stalling EPO for %s" % self.setup2str(SUD);
         self.wreg(rEPSTALLS,0x23); #All three stall bits.
     def SETBIT(self,reg,val):
         """Set a bit in a register."""
@@ -543,7 +562,9 @@ class GoodFETMAXUSBHID(GoodFETMAXUSB):
     MAX3420 examples."""
     def hidinit(self):
         """Initialize a USB HID device."""
+        self.usb_disconnect();
         self.usb_connect();
+        
         self.hidrun();
         
     def hidrun(self):
@@ -558,7 +579,8 @@ class GoodFETMAXUSBHID(GoodFETMAXUSB):
         SUD=self.readbytes(rSUDFIFO,8);
         
         #Parse the SETUP packet
-        print "Handling a setup packet type 0x%02x" % ord(SUD[bmRequestType]);
+        print "Handling a setup packet of %s" % self.setup2str(SUD);
+        
         setuptype=(ord(SUD[bmRequestType])&0x60);
         if setuptype==0x00:
             self.std_request(SUD);
@@ -568,19 +590,19 @@ class GoodFETMAXUSBHID(GoodFETMAXUSB):
             self.vendor_request(SUD);
         else:
             print "Unknown request type 0x%02x." % ord(SUD[bmRequestType])
-            self.STALL_EP0();
+            self.STALL_EP0(SUD);
     def class_request(self,SUD):
         """Handle a class request."""
         print "Stalling a class request.";
-        self.STALL_EP0();
+        self.STALL_EP0(SUD);
     def vendor_request(self,SUD):
         print "Stalling a vendor request.";
-        self.STALL_EP0();
+        self.STALL_EP0(SUD);
     def std_request(self,SUD):
         """Handles a standard setup request."""
         setuptype=ord(SUD[bRequest]);
         if setuptype==SR_GET_DESCRIPTOR: self.send_descriptor(SUD);
-        elif setuptype==SR_SET_FEATURE: self.feature(1);
+        #elif setuptype==SR_SET_FEATURE: self.feature(1);
         elif setuptype==SR_SET_CONFIGURATION: self.set_configuration(SUD);
         elif setuptype==SR_GET_STATUS: self.get_status(SUD);
         elif setuptype==SR_SET_ADDRESS: self.rregAS(rFNADDR);
@@ -588,7 +610,7 @@ class GoodFETMAXUSBHID(GoodFETMAXUSB):
         else:
             print "Stalling Unknown standard setup request type %02x" % setuptype;
             
-            self.STALL_EP0();
+            self.STALL_EP0(SUD);
     
     def get_interface(self,SUD):
         """Handles a setup request for SR_GET_INTERFACE."""
@@ -596,9 +618,9 @@ class GoodFETMAXUSBHID(GoodFETMAXUSB):
             self.wreg(rEP0FIFO,0);
             self.wregAS(rEP0BC,1);
         else:
-            self.STALL_EP0();
+            self.STALL_EP0(SUD);
     
-    #Device Descriptor
+#Device Descriptor
     DD=[0x12,                  # bLength = 18d
         0x01,                  # bDescriptorType = Device (1)
         0x00,0x01,             # bcdUSB(L/H) USB spec rev (BCD)
@@ -609,7 +631,7 @@ class GoodFETMAXUSBHID(GoodFETMAXUSB):
        0x34,0x12,              # bcdDevice--1234
        1,2,3,                  # iManufacturer, iProduct, iSerialNumber
        1];
-    #Configuration Descriptor
+#Configuration Descriptor
     CD=[0x09,                  # bLength
        0x02,                   # bDescriptorType = Config
        0x22,0x00,              # wTotalLength(L/H) = 34 bytes
@@ -731,7 +753,7 @@ class GoodFETMAXUSBHID(GoodFETMAXUSB):
             self.wregAS(rEP0BC,sendlen);
         else:
             print "Stalling in send_descriptor() for lack of handler for %02x." % desctype;
-            self.STALL_EP0();
+            self.STALL_EP0(SUD);
     def set_configuration(self,SUD):
         """Set the configuration."""
         bmSUSPIE=0x10;
@@ -760,9 +782,9 @@ class GoodFETMAXUSBHID(GoodFETMAXUSB):
                 self.wreg(rEP0FIFO,0x00); #Second byte is always zero.
                 self.wregAS(rEP0BC,2);
             else:
-                self.STALL_EP0();
+                self.STALL_EP0(SUD);
         else:
-            self.STALL_EP0();
+            self.STALL_EP0(SUD);
     def service_irqs(self):
         """Handle USB interrupt events."""