]> git.zerfleddert.de Git - proxmark3-svn/blame - common/usb.c
Split str* and mem* into string.[ch]
[proxmark3-svn] / common / usb.c
CommitLineData
fdcc61d3 1//-----------------------------------------------------------------------------
2// My USB driver. This has to be common, because it exists in both the
3// bootrom and the application.
4// Jonathan Westhues, split Aug 14 2005
5//-----------------------------------------------------------------------------
6#include <proxmark3.h>
7
8#define min(a, b) (((a) > (b)) ? (b) : (a))
9
10#define USB_REPORT_PACKET_SIZE 64
11
12typedef struct PACKED {
f7e3ed82 13 uint8_t bmRequestType;
14 uint8_t bRequest;
15 uint16_t wValue;
16 uint16_t wIndex;
17 uint16_t wLength;
fdcc61d3 18} UsbSetupData;
19
20#define USB_REQUEST_GET_STATUS 0
21#define USB_REQUEST_CLEAR_FEATURE 1
22#define USB_REQUEST_SET_FEATURE 3
23#define USB_REQUEST_SET_ADDRESS 5
24#define USB_REQUEST_GET_DESCRIPTOR 6
25#define USB_REQUEST_SET_DESCRIPTOR 7
26#define USB_REQUEST_GET_CONFIGURATION 8
27#define USB_REQUEST_SET_CONFIGURATION 9
28#define USB_REQUEST_GET_INTERFACE 10
29#define USB_REQUEST_SET_INTERFACE 11
30#define USB_REQUEST_SYNC_FRAME 12
31
32#define USB_DESCRIPTOR_TYPE_DEVICE 1
33#define USB_DESCRIPTOR_TYPE_CONFIGURATION 2
34#define USB_DESCRIPTOR_TYPE_STRING 3
35#define USB_DESCRIPTOR_TYPE_INTERFACE 4
36#define USB_DESCRIPTOR_TYPE_ENDPOINT 5
37#define USB_DESCRIPTOR_TYPE_DEVICE_QUALIFIER 6
38#define USB_DESCRIPTOR_TYPE_OTHER_SPEED_CONF 7
39#define USB_DESCRIPTOR_TYPE_INTERFACE_POWER 8
40#define USB_DESCRIPTOR_TYPE_HID 0x21
41#define USB_DESCRIPTOR_TYPE_HID_REPORT 0x22
42
43#define USB_DEVICE_CLASS_HID 0x03
44
f7e3ed82 45static const uint8_t HidReportDescriptor[] = {
fdcc61d3 46 0x06,0xA0,0xFF, // Usage Page (vendor defined) FFA0
47 0x09,0x01, // Usage (vendor defined)
48 0xA1,0x01, // Collection (Application)
49 0x09,0x02, // Usage (vendor defined)
50 0xA1,0x00, // Collection (Physical)
51 0x06,0xA1,0xFF, // Usage Page (vendor defined)
52
53 //The,input report
54 0x09,0x03, // usage - vendor defined
55 0x09,0x04, // usage - vendor defined
56 0x15,0x80, // Logical Minimum (-128)
57 0x25,0x7F, // Logical Maximum (127)
58 0x35,0x00, // Physical Minimum (0)
59 0x45,0xFF, // Physical Maximum (255)
60 0x75,0x08, // Report Size (8) (bits)
61 0x95,0x40, // Report Count (64) (fields)
62 0x81,0x02, // Input (Data,Variable,Absolute)
63
64 //The,output report
65 0x09,0x05, // usage - vendor defined
66 0x09,0x06, // usage - vendor defined
67 0x15,0x80, // Logical Minimum (-128)
68 0x25,0x7F, // Logical Maximum (127)
69 0x35,0x00, // Physical Minimum (0)
70 0x45,0xFF, // Physical Maximum (255)
71 0x75,0x08, // Report Size (8) (bits)
72 0x95,0x40, // Report Count (64) (fields)
73 0x91,0x02, // Output (Data,Variable,Absolute)
74
75 0xC0, // End Collection
76
77 0xC0, // End Collection
78};
79
f7e3ed82 80static const uint8_t DeviceDescriptor[] = {
fdcc61d3 81 0x12, // Descriptor length (18 bytes)
82 0x01, // Descriptor type (Device)
83 0x10,0x01, // Complies with USB Spec. Release (0110h = release 1.10)
84 0x00, // Class code (0)
85 0x00, // Subclass code (0)
86 0x00, // Protocol (No specific protocol)
87 0x08, // Maximum packet size for Endpoint 0 (8 bytes)
88 0xc4,0x9a, // Vendor ID (random numbers)
89 0x8f,0x4b, // Product ID (random numbers)
90 0x01,0x00, // Device release number (0001)
91 0x01, // Manufacturer string descriptor index
92 0x02, // Product string descriptor index
93 0x00, // Serial Number string descriptor index (None)
94 0x01, // Number of possible configurations (1)
95};
96
f7e3ed82 97static const uint8_t ConfigurationDescriptor[] = {
fdcc61d3 98 0x09, // Descriptor length (9 bytes)
99 0x02, // Descriptor type (Configuration)
100 0x29,0x00, // Total data length (41 bytes)
101 0x01, // Interface supported (1)
102 0x01, // Configuration value (1)
103 0x00, // Index of string descriptor (None)
104 0x80, // Configuration (Bus powered)
105 250, // Maximum power consumption (500mA)
106
107 //interface
108 0x09, // Descriptor length (9 bytes)
109 0x04, // Descriptor type (Interface)
110 0x00, // Number of interface (0)
111 0x00, // Alternate setting (0)
112 0x02, // Number of interface endpoint (2)
113 0x03, // Class code (HID)
114 0x00, // Subclass code ()
115 0x00, // Protocol code ()
116 0x00, // Index of string()
117
118 // class
119 0x09, // Descriptor length (9 bytes)
120 0x21, // Descriptor type (HID)
121 0x00,0x01, // HID class release number (1.00)
122 0x00, // Localized country code (None)
123 0x01, // # of HID class dscrptr to follow (1)
124 0x22, // Report descriptor type (HID)
125 // Total length of report descriptor
126 sizeof(HidReportDescriptor),0x00,
127
128 // endpoint 1
129 0x07, // Descriptor length (7 bytes)
130 0x05, // Descriptor type (Endpoint)
131 0x01, // Encoded address (Respond to OUT)
132 0x03, // Endpoint attribute (Interrupt transfer)
133 0x08,0x00, // Maximum packet size (8 bytes)
134 0x01, // Polling interval (1 ms)
135
136 // endpoint 2
137 0x07, // Descriptor length (7 bytes)
138 0x05, // Descriptor type (Endpoint)
139 0x82, // Encoded address (Respond to IN)
140 0x03, // Endpoint attribute (Interrupt transfer)
141 0x08,0x00, // Maximum packet size (8 bytes)
142 0x01, // Polling interval (1 ms)
143};
144
f7e3ed82 145static const uint8_t StringDescriptor0[] = {
fdcc61d3 146 0x04, // Length
147 0x03, // Type is string
148 0x09, // English
149 0x04, // US
150};
151
f7e3ed82 152static const uint8_t StringDescriptor1[] = {
fdcc61d3 153 24, // Length
154 0x03, // Type is string
155 'J', 0x00,
156 '.', 0x00,
157 ' ', 0x00,
158 'W', 0x00,
159 'e', 0x00,
160 's', 0x00,
161 't', 0x00,
162 'h', 0x00,
163 'u', 0x00,
164 'e', 0x00,
165 's', 0x00,
166};
167
f7e3ed82 168static const uint8_t StringDescriptor2[] = {
fdcc61d3 169 54, // Length
170 0x03, // Type is string
171 'P', 0x00,
172 'r', 0x00,
173 'o', 0x00,
174 'x', 0x00,
175 'M', 0x00,
176 'a', 0x00,
177 'r', 0x00,
178 'k', 0x00,
179 '-', 0x00,
180 '3', 0x00,
181 ' ', 0x00,
182 'R', 0x00,
183 'F', 0x00,
184 'I', 0x00,
185 'D', 0x00,
186 ' ', 0x00,
187 'I', 0x00,
188 'n', 0x00,
189 's', 0x00,
190 't', 0x00,
191 'r', 0x00,
192 'u', 0x00,
193 'm', 0x00,
194 'e', 0x00,
195 'n', 0x00,
196 't', 0x00,
197};
198
f7e3ed82 199static const uint8_t * const StringDescriptors[] = {
fdcc61d3 200 StringDescriptor0,
201 StringDescriptor1,
202 StringDescriptor2,
203};
204
205
f7e3ed82 206static uint8_t UsbBuffer[64];
fdcc61d3 207static int UsbSoFarCount;
208
f7e3ed82 209static uint8_t CurrentConfiguration;
fdcc61d3 210
f7e3ed82 211static void UsbSendEp0(const uint8_t *data, int len)
fdcc61d3 212{
213 int thisTime, i;
214
215 do {
216 thisTime = min(len, 8);
217 len -= thisTime;
218
219 for(i = 0; i < thisTime; i++) {
220 AT91C_BASE_UDP->UDP_FDR[0] = *data;
221 data++;
222 }
223
224 if(AT91C_BASE_UDP->UDP_CSR[0] & AT91C_UDP_TXCOMP) {
225 AT91C_BASE_UDP->UDP_CSR[0] &= ~AT91C_UDP_TXCOMP;
226 while(AT91C_BASE_UDP->UDP_CSR[0] & AT91C_UDP_TXCOMP)
227 ;
228 }
229
230 AT91C_BASE_UDP->UDP_CSR[0] |= AT91C_UDP_TXPKTRDY;
231
232 do {
233 if(AT91C_BASE_UDP->UDP_CSR[0] & AT91C_UDP_RX_DATA_BK0) {
234 // This means that the host is trying to write to us, so
235 // abandon our write to them.
236 AT91C_BASE_UDP->UDP_CSR[0] &= ~AT91C_UDP_RX_DATA_BK0;
237 return;
238 }
239 } while(!(AT91C_BASE_UDP->UDP_CSR[0] & AT91C_UDP_TXCOMP));
240 } while(len > 0);
241
242 if(AT91C_BASE_UDP->UDP_CSR[0] & AT91C_UDP_TXCOMP) {
243 AT91C_BASE_UDP->UDP_CSR[0] &= ~AT91C_UDP_TXCOMP;
244 while(AT91C_BASE_UDP->UDP_CSR[0] & AT91C_UDP_TXCOMP)
245 ;
246 }
247}
248
249static void UsbSendZeroLength(void)
250{
251 AT91C_BASE_UDP->UDP_CSR[0] |= AT91C_UDP_TXPKTRDY;
252
253 while(!(AT91C_BASE_UDP->UDP_CSR[0] & AT91C_UDP_TXCOMP))
254 ;
255
256 AT91C_BASE_UDP->UDP_CSR[0] &= ~AT91C_UDP_TXCOMP;
257
258 while(AT91C_BASE_UDP->UDP_CSR[0] & AT91C_UDP_TXCOMP)
259 ;
260}
261
262static void UsbSendStall(void)
263{
264 AT91C_BASE_UDP->UDP_CSR[0] |= AT91C_UDP_FORCESTALL;
265
266 while(!(AT91C_BASE_UDP->UDP_CSR[0] & AT91C_UDP_STALLSENT))
267 ;
268
269 AT91C_BASE_UDP->UDP_CSR[0] &= ~AT91C_UDP_STALLSENT;
270
271 while(AT91C_BASE_UDP->UDP_CSR[0] & AT91C_UDP_STALLSENT)
272 ;
273}
274
275static void HandleRxdSetupData(void)
276{
277 int i;
278 UsbSetupData usd;
279
280 for(i = 0; i < sizeof(usd); i++) {
f7e3ed82 281 ((uint8_t *)&usd)[i] = AT91C_BASE_UDP->UDP_FDR[0];
fdcc61d3 282 }
283
284 if(usd.bmRequestType & 0x80) {
285 AT91C_BASE_UDP->UDP_CSR[0] |= AT91C_UDP_DIR;
286 while(!(AT91C_BASE_UDP->UDP_CSR[0] & AT91C_UDP_DIR))
287 ;
288 }
289
290 AT91C_BASE_UDP->UDP_CSR[0] &= ~AT91C_UDP_RXSETUP;
291 while(AT91C_BASE_UDP->UDP_CSR[0] & AT91C_UDP_RXSETUP)
292 ;
293
294 switch(usd.bRequest) {
295 case USB_REQUEST_GET_DESCRIPTOR:
296 if((usd.wValue >> 8) == USB_DESCRIPTOR_TYPE_DEVICE) {
f7e3ed82 297 UsbSendEp0((uint8_t *)&DeviceDescriptor,
fdcc61d3 298 min(sizeof(DeviceDescriptor), usd.wLength));
299 } else if((usd.wValue >> 8) == USB_DESCRIPTOR_TYPE_CONFIGURATION) {
f7e3ed82 300 UsbSendEp0((uint8_t *)&ConfigurationDescriptor,
fdcc61d3 301 min(sizeof(ConfigurationDescriptor), usd.wLength));
302 } else if((usd.wValue >> 8) == USB_DESCRIPTOR_TYPE_STRING) {
f7e3ed82 303 const uint8_t *s = StringDescriptors[usd.wValue & 0xff];
fdcc61d3 304 UsbSendEp0(s, min(s[0], usd.wLength));
305 } else if((usd.wValue >> 8) == USB_DESCRIPTOR_TYPE_HID_REPORT) {
f7e3ed82 306 UsbSendEp0((uint8_t *)&HidReportDescriptor,
fdcc61d3 307 min(sizeof(HidReportDescriptor), usd.wLength));
308 } else {
f7e3ed82 309 *((uint32_t *)0x00200000) = usd.wValue;
fdcc61d3 310 }
311 break;
312
313 case USB_REQUEST_SET_ADDRESS:
314 UsbSendZeroLength();
315 AT91C_BASE_UDP->UDP_FADDR = AT91C_UDP_FEN | usd.wValue ;
316 if(usd.wValue != 0) {
317 AT91C_BASE_UDP->UDP_GLBSTATE = AT91C_UDP_FADDEN;
318 } else {
319 AT91C_BASE_UDP->UDP_GLBSTATE = 0;
320 }
321 break;
322
323 case USB_REQUEST_GET_CONFIGURATION:
324 UsbSendEp0(&CurrentConfiguration, sizeof(CurrentConfiguration));
325 break;
326
327 case USB_REQUEST_GET_STATUS: {
328 if(usd.bmRequestType & 0x80) {
f7e3ed82 329 uint16_t w = 0;
330 UsbSendEp0((uint8_t *)&w, sizeof(w));
fdcc61d3 331 }
332 break;
333 }
334 case USB_REQUEST_SET_CONFIGURATION:
335 CurrentConfiguration = usd.wValue;
336 if(CurrentConfiguration) {
337 AT91C_BASE_UDP->UDP_GLBSTATE = AT91C_UDP_CONFG;
338 AT91C_BASE_UDP->UDP_CSR[1] = AT91C_UDP_EPEDS |
339 AT91C_UDP_EPTYPE_INT_OUT;
340 AT91C_BASE_UDP->UDP_CSR[2] = AT91C_UDP_EPEDS |
341 AT91C_UDP_EPTYPE_INT_IN;
342 } else {
343 AT91C_BASE_UDP->UDP_GLBSTATE = AT91C_UDP_FADDEN;
344 AT91C_BASE_UDP->UDP_CSR[1] = 0;
345 AT91C_BASE_UDP->UDP_CSR[2] = 0;
346 }
347 UsbSendZeroLength();
348 break;
349
350 case USB_REQUEST_GET_INTERFACE: {
f7e3ed82 351 uint8_t b = 0;
fdcc61d3 352 UsbSendEp0(&b, sizeof(b));
353 break;
354 }
355
356 case USB_REQUEST_SET_INTERFACE:
357 UsbSendZeroLength();
358 break;
359
360 case USB_REQUEST_CLEAR_FEATURE:
361 case USB_REQUEST_SET_FEATURE:
362 UsbSendStall();
363 break;
364 case USB_REQUEST_SET_DESCRIPTOR:
365 case USB_REQUEST_SYNC_FRAME:
366 default:
367 break;
368 }
369}
370
f7e3ed82 371void UsbSendPacket(uint8_t *packet, int len)
fdcc61d3 372{
373 int i, thisTime;
374
375 while(len > 0) {
376 thisTime = min(len, 8);
377
378 for(i = 0; i < thisTime; i++) {
379 AT91C_BASE_UDP->UDP_FDR[2] = packet[i];
380 }
381 AT91C_BASE_UDP->UDP_CSR[2] |= AT91C_UDP_TXPKTRDY;
382
383 while(!(AT91C_BASE_UDP->UDP_CSR[2] & AT91C_UDP_TXCOMP))
384 ;
385 AT91C_BASE_UDP->UDP_CSR[2] &= ~AT91C_UDP_TXCOMP;
386
387 while(AT91C_BASE_UDP->UDP_CSR[2] & AT91C_UDP_TXCOMP)
388 ;
389
390 len -= thisTime;
391 packet += thisTime;
392 }
393}
394
395static void HandleRxdData(void)
396{
397 int i, len;
398
399 if(AT91C_BASE_UDP->UDP_CSR[1] & AT91C_UDP_RX_DATA_BK0) {
400 len = UDP_CSR_BYTES_RECEIVED(AT91C_BASE_UDP->UDP_CSR[1]);
401
402 for(i = 0; i < len; i++) {
403 UsbBuffer[UsbSoFarCount] = AT91C_BASE_UDP->UDP_FDR[1];
404 UsbSoFarCount++;
405 }
406
407 AT91C_BASE_UDP->UDP_CSR[1] &= ~AT91C_UDP_RX_DATA_BK0;
408 while(AT91C_BASE_UDP->UDP_CSR[1] & AT91C_UDP_RX_DATA_BK0)
409 ;
410
411 if(UsbSoFarCount >= 64) {
412 UsbPacketReceived(UsbBuffer, UsbSoFarCount);
413 UsbSoFarCount = 0;
414 }
415 }
416
417 if(AT91C_BASE_UDP->UDP_CSR[1] & AT91C_UDP_RX_DATA_BK1) {
418 len = UDP_CSR_BYTES_RECEIVED(AT91C_BASE_UDP->UDP_CSR[1]);
419
420 for(i = 0; i < len; i++) {
421 UsbBuffer[UsbSoFarCount] = AT91C_BASE_UDP->UDP_FDR[1];
422 UsbSoFarCount++;
423 }
424
425 AT91C_BASE_UDP->UDP_CSR[1] &= ~AT91C_UDP_RX_DATA_BK1;
426 while(AT91C_BASE_UDP->UDP_CSR[1] & AT91C_UDP_RX_DATA_BK1)
427 ;
428
429 if(UsbSoFarCount >= 64) {
430 UsbPacketReceived(UsbBuffer, UsbSoFarCount);
431 UsbSoFarCount = 0;
432 }
433 }
434}
435
436void UsbStart(void)
437{
438 volatile int i;
439
440 UsbSoFarCount = 0;
441
442 USB_D_PLUS_PULLUP_OFF();
443
444 for(i = 0; i < 1000000; i++)
445 ;
446
447 USB_D_PLUS_PULLUP_ON();
448
449 if(AT91C_BASE_UDP->UDP_ISR & AT91C_UDP_ENDBUSRES) {
450 AT91C_BASE_UDP->UDP_ICR = AT91C_UDP_ENDBUSRES;
451 }
452}
453
f7e3ed82 454int UsbConnected()
fdcc61d3 455{
456 if (AT91C_BASE_UDP->UDP_GLBSTATE & AT91C_UDP_CONFG)
457 return TRUE;
458 else
459 return FALSE;
460}
461
f7e3ed82 462int UsbPoll(int blinkLeds)
fdcc61d3 463{
f7e3ed82 464 int ret = FALSE;
fdcc61d3 465
466 if(AT91C_BASE_UDP->UDP_ISR & AT91C_UDP_ENDBUSRES) {
467 AT91C_BASE_UDP->UDP_ICR = AT91C_UDP_ENDBUSRES;
468
469 // following a reset we should be ready to receive a setup packet
470 AT91C_BASE_UDP->UDP_RSTEP = 0xf;
471 AT91C_BASE_UDP->UDP_RSTEP = 0;
472
473 AT91C_BASE_UDP->UDP_FADDR = AT91C_UDP_FEN;
474
475 AT91C_BASE_UDP->UDP_CSR[0] = AT91C_UDP_EPTYPE_CTRL | AT91C_UDP_EPEDS;
476
477 CurrentConfiguration = 0;
478
479 ret = TRUE;
480 }
481
482 if(AT91C_BASE_UDP->UDP_ISR & UDP_INTERRUPT_ENDPOINT(0)) {
483 if(AT91C_BASE_UDP->UDP_CSR[0] & AT91C_UDP_RXSETUP) {
484 HandleRxdSetupData();
485 ret = TRUE;
486 }
487 }
488
489 if(AT91C_BASE_UDP->UDP_ISR & UDP_INTERRUPT_ENDPOINT(1)) {
490 HandleRxdData();
491 ret = TRUE;
492 }
493
494 return ret;
495}
Impressum, Datenschutz