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
class GoodFETMAXUSB(GoodFET):
MAXUSBAPP=0x40;
+ usbverbose=True;
+
+ def service_irqs(self):
+ """Handle USB interrupt events."""
+ epirq=self.rreg(rEPIRQ);
+ usbirq=self.rreg(rUSBIRQ);
+
+
+ #Are we being asked for setup data?
+ if(epirq&bmSUDAVIRQ): #Setup Data Requested
+ self.wreg(rEPIRQ,bmSUDAVIRQ); #Clear the bit
+ self.do_SETUP();
+ if(epirq&bmOUT1DAVIRQ): #OUT1-OUT packet
+ self.do_OUT1();
+ self.wreg(rEPIRQ,bmOUT1DAVIRQ); #Clear the bit *AFTER* servicing.
+ if(epirq&bmIN3BAVIRQ): #IN3-IN packet
+ self.do_IN3();
+ #self.wreg(rEPIRQ,bmIN3BAVIRQ); #Clear the bit
+ if(epirq&bmIN2BAVIRQ): #IN2 packet
+ self.do_IN2();
+ #self.wreg(rEPIRQ,bmIN2BAVIRQ); #Clear the bit
+ #else:
+ # print "No idea how to service this IRQ: %02x" % epirq;
+ def do_IN2(self):
+ """Overload this."""
+ def do_IN3(self):
+ """Overload this."""
+ def do_OUT1(self):
+ """Overload this."""
+ if self.usbverbose: print "Ignoring an OUT1 interrupt.";
+ 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
ashex="";
for foo in toret:
ashex=ashex+(" %02x"%ord(foo));
- print "GET %02x==%s" % (reg,ashex);
+ if self.usbverbose: print "GET %02x==%s" % (reg,ashex);
+ return toret;
+ def readbytesAS(self,reg,length):
+ """Peek some bytes from a register, acking prior transfer."""
+ data=[(reg<<3)|1]+range(0,length);
+ self.writecmd(self.MAXUSBAPP,0x00,len(data),data);
+ toret=self.data[1:len(self.data)];
+ ashex="";
+ for foo in toret:
+ ashex=ashex+(" %02x"%ord(foo));
+ if self.usbverbose: print "GETAS %02x==%s" % (reg,ashex);
return toret;
def ctl_write_nd(self,request):
"""Control Write with no data stage. Assumes PERADDR is set
"""Poke some bytes into a register."""
data="";
if type(tosend)==str:
- data=chr((reg<<3)|2)+tosend;
+ data=chr((reg<<3)|3)+tosend;
+ if self.usbverbose: print "PUT %02x:=%s (0x%02x bytes)" % (reg,tosend,len(data))
else:
- data=[(reg<<3)|2]+tosend;
+ data=[(reg<<3)|3]+tosend;
ashex="";
for foo in tosend:
ashex=ashex+(" %02x"%foo);
- print "PUT %02x:=%s" % (reg,ashex)
+ if self.usbverbose: print "PUT %02x:=%s (0x%02x bytes)" % (reg,ashex,len(data))
self.writecmd(self.MAXUSBAPP,0x00,len(data),data);
def usb_connect(self):
"""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."""
for c in self.xfrdata[2:len(self.xfrdata)]:
if c>0: toret=toret+chr(c);
return toret;
+class GoodFETMAXUSBDevice(GoodFETMAXUSB):
+
+ 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]);
-class GoodFETMAXUSBHID(GoodFETMAXUSB):
+ 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=ord(self.strDesc[ord(SUD[wValueL])][0]);
+ ddata=self.strDesc[ord(SUD[wValueL])];
+ elif desctype==GD_HID:
+ #Don't know how to do this yet.
+ pass;
+ elif desctype==GD_REPORT:
+ desclen=self.CD[25];
+ ddata=self.RepD;
+ #TODO Configuration, String, Hid, and Report
+
+ if desclen>0:
+ #Reduce desclen if asked for fewer bytes.
+ desclen=min(reqlen,desclen);
+ #Send those bytes.
+ self.writebytes(rEP0FIFO,ddata[0:desclen]);
+ self.wregAS(rEP0BC,desclen);
+ 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;
+ configval=ord(SUD[wValueL]);
+ if(configval>0):
+ self.SETBIT(rUSBIEN,bmSUSPIE);
+ self.rregAS(rFNADDR);
+class GoodFETMAXUSBHID(GoodFETMAXUSBDevice):
"""This is an example HID keyboard driver, loosely based on the
MAX3420 examples."""
def hidinit(self):
"""Initialize a USB HID device."""
+ self.usb_disconnect();
self.usb_connect();
+
self.hidrun();
def hidrun(self):
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);
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.rregAS(rFNADDR);
+ # # 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);
elif setuptype==SR_GET_INTERFACE: self.get_interface(SUD);
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."""
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)
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
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();
- def set_configuration(self,SUD):
- """Set the configuration."""
- bmSUSPIE=0x10;
- configval=ord(SUD[wValueL]);
- if(configval>0):
- self.SETBIT(rUSBIEN,bmSUSPIE);
- self.rregAS(rFNADDR);
+
def get_status(self,SUD):
"""Get the USB Setup Status."""
testbyte=ord(SUD[bmRequestType])
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();
- def service_irqs(self):
- """Handle USB interrupt events."""
-
- epirq=self.rreg(rEPIRQ);
- usbirq=self.rreg(rUSBIRQ);
-
- #Are we being asked for setup data?
- if(epirq&bmSUDAVIRQ): #Setup Data Requested
- self.wreg(rEPIRQ,bmSUDAVIRQ); #Clear the bit
- self.do_SETUP();
- if(epirq&bmIN3BAVIRQ): #EN3-IN packet
- self.do_IN3();
-
+ self.STALL_EP0(SUD);
+
+
typephase=0;
typestring=" Python does USB HID!";