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