3 #USB Mass Storage Emulator
5 #with thanks to Brandon Wilson and his Linky project.
12 from GoodFETMAXUSB import *;
14 class GoodFETMAXUSBMass(GoodFETMAXUSBDevice):
15 """This emulates a USB Mass Storage device."""
17 """Initialize a USB Mass Storage device."""
18 self.usb_disconnect();
24 """Main loop of the USB Mass Storage emulator."""
25 print "Starting a Mass Storage device. This doesn't work yet.";
29 """Handle USB Enumeration"""
31 #Grab the SETUP packet from the buffer.
32 SUD=self.readbytes(rSUDFIFO,8);
34 #Parse the SETUP packet
35 print "Handling a setup packet of %s" % self.setup2str(SUD);
36 setuptype=(ord(SUD[bmRequestType])&0x60);
38 self.std_request(SUD);
40 self.class_request(SUD);
42 self.vendor_request(SUD);
44 print "Unknown bmRequestType=0x%02x." % ord(SUD[bmRequestType])
46 def class_request(self,SUD):
47 """Handle a class request."""
48 requesttype=ord(SUD[bmRequestType]);
49 request=ord(SUD[bRequest]);
50 if requesttype==0xA1 and request==0xFE:
51 print "Reporting 0 as the maximum LUN.";
52 #This is a Get Max LUN request.
53 #Return 1-byte maximum Logical Unit Number
54 self.wreg(rEP0FIFO,0x00); # Just one LUN.
55 self.wregAS(rEP0BC,1); # ARM and fire!
57 if requesttype==0x21 and request==0xff:
58 print "Received BBB reset."
59 self.wregAS(rEP0BC,0); # ARM and fire!
61 print "Stalling an unknown class request: %s" % self.setup2str(SUD);
63 def vendor_request(self,SUD):
64 """Handle a vendor request."""
65 request=ord(SUD[bRequest]);
66 print "Why the hell is there a vendor request?";
67 #self.wreg(rEP0FIFO,0);
68 self.wregAS(rEP0BC,0);
69 def std_request(self,SUD):
70 """Handles a standard setup request."""
71 setuptype=ord(SUD[bRequest]);
72 if setuptype==SR_GET_DESCRIPTOR: self.send_descriptor(SUD);
73 #elif setuptype==SR_SET_FEATURE: self.feature(1);
74 elif setuptype==SR_SET_CONFIGURATION: self.set_configuration(SUD);
75 elif setuptype==SR_GET_STATUS: self.get_status(SUD);
76 elif setuptype==SR_SET_ADDRESS: self.rregAS(rFNADDR);
77 elif setuptype==SR_GET_INTERFACE: self.get_interface(SUD);
79 #print "Stalling Unknown standard setup request type %02x" % setuptype;
81 print "Accepting unknown standard setup request type %02x" % setuptype;
82 self.wregAS(rEP0BC,0);
84 def get_interface(self,SUD):
85 """Handles a setup request for SR_GET_INTERFACE."""
86 if ord(SUD[wIndexL]==0):
87 self.wreg(rEP0FIFO,0);
88 self.wregAS(rEP0BC,1);
98 0x01, 0x00, 0x02, 0x00, 0x00, 0x00, 0x40,
100 0x50, 0x51, #SDCZ2 Cruzer Mini Flash Drive (thin)
102 0x01, 0x02, 0x03, #Strings
107 #Configuration Descriptor
113 0x00, 0x01, 0x01, 0x00, 0xE0, 0x00, 0x09, 0x04, 0x00, 0x00,
115 0x08, #Mass Storage Bulk Only
120 0x07, 0x05, 0x01, 0x02, 0x40, 0x00, 0x00,
122 0x07, 0x05, 0x83, 0x02, 0x40, 0x00, 0x00,
126 # STRING descriptor 0--Language string
130 # 0x03, # bDescriptorType = string
131 # 0x09,0x04 # wLANGID(L/H) = English-United Sates
133 # STRING descriptor 1--Manufacturer ID
134 "\x10\x03G\x00o\x00o\x00d\x00F\x00E\x00T\x00",
135 # STRING descriptor 2 - Product ID
136 "\x1C\x03M\x00A\x00S\x00S\x00 \x00E\x00m\x00u\x00l\x00a\x00t\x00o\x00r\x00",
137 # STRING descriptor 3 - Serial Number ID
138 "\x14\x03S\x00/\x00N\x00 \x003\x004\x002\x000\x00E\x00"
141 def get_status(self,SUD):
142 """Get the USB Setup Status."""
143 testbyte=ord(SUD[bmRequestType])
147 self.wreg(rEP0FIFO,0x03); #Enable RWU and self-powered
148 self.wreg(rEP0FIFO,0x00); #Second byte is always zero.
149 self.wregAS(rEP0BC,2); #Load byte count, arm transfer, and ack CTL.
152 self.wreg(rEP0FIFO,0x00);
153 self.wreg(rEP0FIFO,0x00); #Second byte is always zero.
154 self.wregAS(rEP0BC,2);
157 if(ord(SUD[wIndexL])==0x83):
158 print "This code almost certainly doesn't work.";
159 self.wreg(rEP0FIFO,0x01); #Stall EP3
160 self.wreg(rEP0FIFO,0x00); #Second byte is always zero.
161 self.wregAS(rEP0BC,2);
163 print "Stalling unknown status.";
166 print "Stalling unknown status.";
170 """Handle IN3 input event."""
171 # Do nothing here, as it'll be taken care of elsewhere. The
172 # interrupt just means that the buffer is empty, not that we
173 # are expected to fill it.
176 """Handle an OUT1 output event."""
177 print "Got an output event, printing the result.";
178 l=self.rreg(rEP1OUTBC);
179 frame=self.readbytes(rEP1OUTFIFO,l);
180 self.handleCBW(frame);
183 def handleCBW(self,cbw):
184 """Handles an incoming Command Block Wrapper. See USB Mass
185 Storage Class for details."""
188 print "Invalid CBW length of %i bytes. Aborting." % len(cbw);
192 print "Invalid CBW signature: %s. Should be USBC; aborting." % sig;
196 dtlen=ord(cbw[8])+(ord(cbw[9])<<8)+(ord(cbw[10])<<16)+(ord(cbw[11])<<24);
198 dtdir=flags&0x80; # 0x80 for dev->host, 0x00 for host->dev
199 lun=ord(cbw[13])&0x0F; # Should be zero, as we only reported one LUN.
200 cblen=ord(cbw[14])&0x1F;
202 self.handleCB(cb,cblen,dtlen,dtdir);
204 def handleCB(self,cb,cblen,dtlen,dtdir):
205 """Handles a command block, then replies with a CSW."""
206 print "\nGot command block 0x%02x, requesting 0x%02x bytes" % (
209 status=00; #good, set to 1 for bad.
210 if verb==0x00: # Test Unit Ready
211 # Send nothing, just the success code.
213 elif verb==0x03: # Request Sense
214 print "Responding to Request Sense. Needed for Macs.";
215 response=[0x70, 0x00, 0xFF, 0x00, 0x00, 0x00, 0x00, 0x0A,
216 0x00, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0x00, 0x00,
220 self.writebytes(rEP3INFIFO,
222 self.wreg(rEP3INBC,len(response));
223 elif verb==0x12: #Inquiry
224 #print "Responding to CB inquiry.";
226 0x00, # 00 for Direct, 1F for "no floppy"
227 0x80, # make 0x80 for removable media
229 0x01, # Response Data Format
230 0x1f, #Additional length.
233 ord('G'),ord('o'),ord('o'),ord('d'),ord('F'),ord('E'),ord('T'),0x20,
235 ord('G'),ord('o'),ord('o'),ord('d'),ord('F'),ord('E'),ord('T'),0x20,
236 0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,
237 ord('0'),ord('.'),ord('0'),ord('1')]
238 #print "Sending %i byte reply to %i byte query." % (
239 # len(response),dtlen);
240 #while not(self.rreg(rEPIRQ)&bmIN3BAVIRQ):
241 # #Wait for the packet to complete before sending the next.
242 # print "Waiting to complete inquiry."
244 self.writebytes(rEP3INFIFO,
246 self.wregAS(rEP3INBC,
249 #self.wreg(rEPIRQ,bmIN3BAVIRQ); #Clear the bit
250 #while not(self.rreg(rEPIRQ)&bmIN3BAVIRQ):
251 # #Wait for the packet to complete before sending the next.
252 # print "Waiting to complete inquiry."
254 elif verb==0x1e: #Prevent/Allow Removal
255 # Give a good status to pretend we understand.
257 elif verb==0x1A: #Mode Sense (6)
258 # I should probably send six bytes here.
259 response=[0x12,0,0,0, 0,0,0,0x1C];
260 self.writebytes(rEP3INFIFO,
262 self.wregAS(rEP3INBC,
264 elif verb==0x23: #Read Format Capacity
266 0x00, 0,0x00,0x08, #Capacity list length.
267 0,0x00,x10,0x00, # Number of sectors, implying 10MB.
268 0x01,0x00, #reserved/desciptor code.
269 0x02,0x00 # 512 bytes/sector. Why is this twice?
271 self.writebytes(rEP3INFIFO,
273 self.wregAS(rEP3INBC,
275 elif verb==0x25: #Read Capacity
277 0x00, 0,0x0f,0xFF, # Last LBA; might have endianness backward.
278 0x00,0x00,0x02,0x00 # Block length of 512 bytes.
280 self.writebytes(rEP3INFIFO,
282 self.wregAS(rEP3INBC,
284 elif verb==0x28: #READ SECTOR
285 print "Haven't implemented READ SECTOR.";
287 elif verb==0x2A: #WRITE SECTOR
288 print "Haven't implemented WRITE SECTOR.";
291 print "ERROR: Unknown SCSI command block verb %02x." % verb;
292 status=1; #Command Failed
294 print "Perhaps I should send %i bytes of dummy data here." % dtlen;
298 #Now we need to send the CSW.
301 ord('U'),ord('S'),ord('B'),ord('S'),
302 #CBW key; must be the same as the one we're replying to.
303 ord(cbw[4]),ord(cbw[5]),ord(cbw[6]),ord(cbw[7]),
304 #CSW Data Residue, probably oughtn't be zeroed.
306 #Status byte: 00 for good, 01 for bad.
308 self.writebytes(rEP3INFIFO,
310 self.wregAS(rEP3INBC,len(csw));
314 #Initialize FET and set baud rate
315 client=GoodFETMAXUSBMass();
318 client.MAXUSBsetup();