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