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;
11 from GoodFET import GoodFET;
36 # R11 EPIRQ register bits
44 # R12 EPIEN register bits
53 # ************************
54 # Standard USB Requests
55 SR_GET_STATUS =0x00 # Get Status
56 SR_CLEAR_FEATURE =0x01 # Clear Feature
57 SR_RESERVED =0x02 # Reserved
58 SR_SET_FEATURE =0x03 # Set Feature
59 SR_SET_ADDRESS =0x05 # Set Address
60 SR_GET_DESCRIPTOR =0x06 # Get Descriptor
61 SR_SET_DESCRIPTOR =0x07 # Set Descriptor
62 SR_GET_CONFIGURATION =0x08 # Get Configuration
63 SR_SET_CONFIGURATION =0x09 # Set Configuration
64 SR_GET_INTERFACE =0x0a # Get Interface
65 SR_SET_INTERFACE =0x0b # Set Interface
67 # Get Descriptor codes
68 GD_DEVICE =0x01 # Get device descriptor: Device
69 GD_CONFIGURATION =0x02 # Get device descriptor: Configuration
70 GD_STRING =0x03 # Get device descriptor: String
71 GD_HID =0x21 # Get descriptor: HID
72 GD_REPORT =0x22 # Get descriptor: Report
74 # SETUP packet offsets
96 class GoodFETMAXUSB(GoodFET):
98 def MAXUSBsetup(self):
99 """Move the FET into the MAXUSB application."""
100 self.writecmd(self.MAXUSBAPP,0x10,0,self.data); #MAXUSB/SETUP
101 print "Connected to MAX342x Rev. %x" % (self.rreg(rREVISION));
102 self.wreg(rPINCTL,0x18); #Set duplex and negative INT level.
104 def MAXUSBtrans8(self,byte):
105 """Read and write 8 bits by MAXUSB."""
106 data=self.MAXUSBtrans([byte]);
109 def MAXUSBtrans(self,data):
110 """Exchange data by MAXUSB."""
112 self.writecmd(self.MAXUSBAPP,0x00,len(data),data);
116 """Peek 8 bits from a register."""
118 self.writecmd(self.MAXUSBAPP,0x00,len(data),data);
119 return ord(self.data[1]);
120 def rregAS(self,reg):
121 """Peek 8 bits from a register, setting AS."""
123 self.writecmd(self.MAXUSBAPP,0x00,len(data),data);
124 return ord(self.data[1]);
125 def wreg(self,reg,value):
126 """Poke 8 bits into a register."""
127 data=[(reg<<3)|2,value];
128 self.writecmd(self.MAXUSBAPP,0x00,len(data),data);
130 def wregAS(self,reg,value):
131 """Poke 8 bits into a register, setting AS."""
132 data=[(reg<<3)|3,value];
133 self.writecmd(self.MAXUSBAPP,0x00,len(data),data);
135 def readbytes(self,reg,length):
136 """Peek some bytes from a register."""
137 data=[(reg<<3)]+range(0,length);
138 self.writecmd(self.MAXUSBAPP,0x00,len(data),data);
139 toret=self.data[1:len(self.data)];
142 ashex=ashex+(" %02x"%ord(foo));
143 print "GET %02x==%s" % (reg,ashex);
145 def writebytes(self,reg,tosend):
146 """Poke some bytes into a register."""
148 if type(tosend)==str:
149 data=chr((reg<<3)|2)+tosend;
151 data=[(reg<<3)|2]+tosend;
154 ashex=ashex+(" %02x"%foo);
155 print "PUT %02x:=%s" % (reg,ashex)
156 self.writecmd(self.MAXUSBAPP,0x00,len(data),data);
157 def usb_connect(self):
158 """Connect the USB port."""
160 #disconnect D+ pullup if host turns off VBUS
161 self.wreg(rUSBCTL,0x48);
163 """Stall for an unknown event."""
165 self.wreg(rEPSTALLS,0x23); #All three stall bits.
166 def SETBIT(self,reg,val):
167 """Set a bit in a register."""
168 self.wreg(reg,self.rreg(reg)|val);
169 class GoodFETMAXUSBHID(GoodFETMAXUSB):
170 """This is an example HID keyboard driver, loosely based on the
173 """Initialize a USB HID device."""
178 """Main loop of the USB HID emulator."""
179 print "Starting a HID device. This won't return.";
183 """Handle USB Enumeration"""
185 #Grab the SETUP packet from the buffer.
186 SUD=self.readbytes(rSUDFIFO,8);
188 #Parse the SETUP packet
189 print "Handling a setup packet type 0x%02x" % ord(SUD[bmRequestType]);
190 setuptype=(ord(SUD[bmRequestType])&0x60);
192 self.std_request(SUD);
193 elif setuptype==0x20:
194 self.class_request(SUD);
195 elif setuptype==0x40:
196 self.vendor_request(SUD);
198 print "Unknown request type 0x%02x." % ord(SUD[bmRequestType])
200 def class_request(self,SUD):
201 """Handle a class request."""
202 print "Stalling a class request.";
204 def vendor_request(self,SUD):
205 print "Stalling a vendor request.";
207 def std_request(self,SUD):
208 """Handles a standard setup request."""
209 setuptype=ord(SUD[bRequest]);
210 if setuptype==SR_GET_DESCRIPTOR: self.send_descriptor(SUD);
211 elif setuptype==SR_SET_FEATURE: self.feature(1);
212 elif setuptype==SR_SET_CONFIGURATION: self.set_configuration(SUD);
213 elif setuptype==SR_GET_STATUS: self.get_status(SUD);
214 elif setuptype==SR_SET_ADDRESS: self.rregAS(rFNADDR);
215 elif setuptype==SR_GET_INTERFACE: self.get_interface(SUD);
217 print "Stalling Unknown standard setup request type %02x" % setuptype;
221 def get_interface(self,SUD):
222 """Handles a setup request for SR_GET_INTERFACE."""
223 if ord(SUD[wIndexL]==0):
224 self.wreg(rEP0FIFO,0);
225 self.wregAS(rEP0BC,1);
230 DD=[0x12, # bLength = 18d
231 0x01, # bDescriptorType = Device (1)
232 0x00,0x01, # bcdUSB(L/H) USB spec rev (BCD)
233 0x00,0x00,0x00, # bDeviceClass, bDeviceSubClass, bDeviceProtocol
234 0x40, # bMaxPacketSize0 EP0 is 64 bytes
235 0x6A,0x0B, # idVendor(L/H)--Maxim is 0B6A
236 0x46,0x53, # idProduct(L/H)--5346
237 0x34,0x12, # bcdDevice--1234
238 1,2,3, # iManufacturer, iProduct, iSerialNumber
240 #Configuration Descriptor
242 0x02, # bDescriptorType = Config
243 0x22,0x00, # wTotalLength(L/H) = 34 bytes
244 0x01, # bNumInterfaces
246 0x00, # iConfiguration
247 0xE0, # bmAttributes. b7=1 b6=self-powered b5=RWU supported
248 0x01, # MaxPower is 2 ma
249 # INTERFACE Descriptor
253 0x00, # bAlternate Setting
254 0x01, # bNum Endpoints
255 0x03, # bInterfaceClass = HID
256 0x00,0x00, # bInterfaceSubClass, bInterfaceProtocol
258 # HID Descriptor--It's at CD[18]
260 0x21, # bDescriptorType = HID
261 0x10,0x01, # bcdHID(L/H) Rev 1.1
262 0x00, # bCountryCode (none)
263 0x01, # bNumDescriptors (one report descriptor)
264 0x22, # bDescriptorType (report)
265 43,0, # CD[25]: wDescriptorLength(L/H) (report descriptor size is 43 bytes)
266 # Endpoint Descriptor
268 0x05, # bDescriptorType (Endpoint)
269 0x83, # bEndpointAddress (EP3-IN)
270 0x03, # bmAttributes (interrupt)
271 64,0, # wMaxPacketSize (64)
274 # STRING descriptor 0--Language string
278 # 0x03, # bDescriptorType = string
279 # 0x09,0x04 # wLANGID(L/H) = English-United Sates
281 # STRING descriptor 1--Manufacturer ID
282 "\x0c\x03M\x00a\x00x\x00i\x00m\x00",
285 # 0x03, # bDescriptorType = string
286 # 'M',0,'a',0,'x',0,'i',0,'m',0 # text in Unicode
288 # STRING descriptor 2 - Product ID
289 "\x18\x03M\x00A\x00X\x003\x004\x002\x000\x00E\x00 \x00E\x00n\x00u\x00m\x00 \x00C\x00o\x00d\x00e\x00",
291 # 0x03, # bDescriptorType = string
292 # 'M',0,'A',0,'X',0,'3',0,'4',0,'2',0,'0',0,'E',0,' ',0,
293 # 'E',0,'n',0,'u',0,'m',0,' ',0,'C',0,'o',0,'d',0,'e',0
297 # STRING descriptor 3 - Serial Number ID
298 "\x14\x03S\x00/\x00N\x00 \x003\x004\x002\x000\x00E\x00"
300 # 0x03, # bDescriptorType = string
313 0x05,0x01, # Usage Page (generic desktop)
314 0x09,0x06, # Usage (keyboard)
315 0xA1,0x01, # Collection
316 0x05,0x07, # Usage Page 7 (keyboard/keypad)
317 0x19,0xE0, # Usage Minimum = 224
318 0x29,0xE7, # Usage Maximum = 231
319 0x15,0x00, # Logical Minimum = 0
320 0x25,0x01, # Logical Maximum = 1
321 0x75,0x01, # Report Size = 1
322 0x95,0x08, # Report Count = 8
323 0x81,0x02, # Input(Data,Variable,Absolute)
324 0x95,0x01, # Report Count = 1
325 0x75,0x08, # Report Size = 8
326 0x81,0x01, # Input(Constant)
327 0x19,0x00, # Usage Minimum = 0
328 0x29,0x65, # Usage Maximum = 101
329 0x15,0x00, # Logical Minimum = 0,
330 0x25,0x65, # Logical Maximum = 101
331 0x75,0x08, # Report Size = 8
332 0x95,0x01, # Report Count = 1
333 0x81,0x00, # Input(Data,Variable,Array)
335 def send_descriptor(self,SUD):
336 """Send the USB descriptors based upon the setup data."""
338 reqlen=ord(SUD[wLengthL])+256*ord(SUD[wLengthH]); #16-bit length
339 desctype=ord(SUD[wValueH]);
341 if desctype==GD_DEVICE:
344 elif desctype==GD_CONFIGURATION:
347 elif desctype==GD_STRING:
348 desclen=self.strDesc[ord(SUD[wValueL])][0];
349 ddata=self.strDesc[ord(SUD[wValueL])];
350 elif desctype==GD_REPORT:
354 #TODO Configuration, String, Hid, and Report
357 sendlen=min(reqlen,desclen);
358 self.writebytes(rEP0FIFO,ddata);
359 self.wregAS(rEP0BC,sendlen);
361 print "Stalling in send_descriptor() for lack of handler for %02x." % desctype;
363 def set_configuration(self,SUD):
364 """Set the configuration."""
366 configval=ord(SUD[wValueL]);
368 self.SETBIT(rUSBIEN,bmSUSPIE);
369 self.rregAS(rFNADDR);
370 def get_status(self,SUD):
371 """Get the USB Setup Status."""
372 testbyte=ord(SUD[bmRequestType])
376 self.wreg(rEP0FIFO,0x03); #Enable RWU and self-powered
377 self.wreg(rEP0FIFO,0x00); #Second byte is always zero.
378 self.wregAS(rEP0BC,2); #Load byte count, arm transfer, and ack CTL.
381 self.wreg(rEP0FIFO,0x00);
382 self.wreg(rEP0FIFO,0x00); #Second byte is always zero.
383 self.wregAS(rEP0BC,2);
386 if(ord(SUD[wIndexL])==0x83):
387 self.wreg(rEP0FIFO,0x01); #Stall EP3
388 self.wreg(rEP0FIFO,0x00); #Second byte is always zero.
389 self.wregAS(rEP0BC,2);
394 def service_irqs(self):
395 """Handle USB interrupt events."""
397 epirq=self.rreg(rEPIRQ);
398 usbirq=self.rreg(rUSBIRQ);
400 #Are we being asked for setup data?
401 if(epirq&bmSUDAVIRQ): #Setup Data Requested
402 self.wreg(rEPIRQ,bmSUDAVIRQ); #Clear the bit
404 if(epirq&bmIN3BAVIRQ): #EN3-IN packet
409 typestring=" Python does USB HID!";
412 def asc2hid(self,ascii):
413 """Translate ASCII to an USB keycode."""
415 if a>='a' and a<='z':
416 return ord(a)-ord('a')+4;
417 elif a>='A' and a<='Z':
418 return ord(a)-ord('A')+4;
424 """Type next letter in buffer."""
425 if self.typepos>=len(self.typestring):
427 elif self.typephase==0:
432 self.typeletter(self.typestring[self.typepos]);
433 self.typepos=self.typepos+1;
435 def typeletter(self,key):
436 """Type a letter on IN3. Zero for keyup."""
437 #if type(key)==str: key=ord(key);
439 self.wreg(rEP3INFIFO,0);
440 self.wreg(rEP3INFIFO,0);
441 self.wreg(rEP3INFIFO,self.asc2hid(key));
442 self.wreg(rEP3INBC,3);
444 """Handle IN3 event."""
445 #Don't bother clearing interrupt flag, that's done by sending the reply.