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 | |
17 | typedef 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 |
50 | static 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 |
85 | static 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 |
602ac4d7 |
98 | 0x03, // Serial Number string descriptor index |
fdcc61d3 |
99 | 0x01, // Number of possible configurations (1) |
100 | }; |
101 | |
f7e3ed82 |
102 | static 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 |
150 | static const uint8_t StringDescriptor0[] = { |
fdcc61d3 |
151 | 0x04, // Length |
152 | 0x03, // Type is string |
153 | 0x09, // English |
154 | 0x04, // US |
155 | }; |
156 | |
f7e3ed82 |
157 | static 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 |
173 | static 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 | |
602ac4d7 |
204 | // Serial Number |
205 | // TODO: Pick yours! Don't forget to modify the length, if needed. |
206 | static const uint8_t StringDescriptor3[] = { |
207 | 18, // Length |
208 | 0x03, // Type is string |
209 | 'C', 0x00, |
210 | 'h', 0x00, |
211 | 'a', 0x00, |
212 | 'n', 0x00, |
213 | 'g', 0x00, |
214 | 'e', 0x00, |
215 | 'M', 0x00, |
216 | 'e', 0x00, |
217 | }; |
218 | |
f7e3ed82 |
219 | static const uint8_t * const StringDescriptors[] = { |
fdcc61d3 |
220 | StringDescriptor0, |
221 | StringDescriptor1, |
222 | StringDescriptor2, |
602ac4d7 |
223 | StringDescriptor3, |
fdcc61d3 |
224 | }; |
225 | |
226 | |
f7e3ed82 |
227 | static uint8_t UsbBuffer[64]; |
fdcc61d3 |
228 | static int UsbSoFarCount; |
229 | |
f7e3ed82 |
230 | static uint8_t CurrentConfiguration; |
fdcc61d3 |
231 | |
f7e3ed82 |
232 | static void UsbSendEp0(const uint8_t *data, int len) |
fdcc61d3 |
233 | { |
234 | int thisTime, i; |
235 | |
236 | do { |
237 | thisTime = min(len, 8); |
238 | len -= thisTime; |
239 | |
240 | for(i = 0; i < thisTime; i++) { |
241 | AT91C_BASE_UDP->UDP_FDR[0] = *data; |
242 | data++; |
243 | } |
244 | |
245 | if(AT91C_BASE_UDP->UDP_CSR[0] & AT91C_UDP_TXCOMP) { |
246 | AT91C_BASE_UDP->UDP_CSR[0] &= ~AT91C_UDP_TXCOMP; |
247 | while(AT91C_BASE_UDP->UDP_CSR[0] & AT91C_UDP_TXCOMP) |
248 | ; |
249 | } |
250 | |
251 | AT91C_BASE_UDP->UDP_CSR[0] |= AT91C_UDP_TXPKTRDY; |
252 | |
253 | do { |
254 | if(AT91C_BASE_UDP->UDP_CSR[0] & AT91C_UDP_RX_DATA_BK0) { |
255 | // This means that the host is trying to write to us, so |
256 | // abandon our write to them. |
257 | AT91C_BASE_UDP->UDP_CSR[0] &= ~AT91C_UDP_RX_DATA_BK0; |
258 | return; |
259 | } |
260 | } while(!(AT91C_BASE_UDP->UDP_CSR[0] & AT91C_UDP_TXCOMP)); |
261 | } while(len > 0); |
262 | |
263 | if(AT91C_BASE_UDP->UDP_CSR[0] & AT91C_UDP_TXCOMP) { |
264 | AT91C_BASE_UDP->UDP_CSR[0] &= ~AT91C_UDP_TXCOMP; |
265 | while(AT91C_BASE_UDP->UDP_CSR[0] & AT91C_UDP_TXCOMP) |
266 | ; |
267 | } |
268 | } |
269 | |
270 | static void UsbSendZeroLength(void) |
271 | { |
272 | AT91C_BASE_UDP->UDP_CSR[0] |= AT91C_UDP_TXPKTRDY; |
273 | |
274 | while(!(AT91C_BASE_UDP->UDP_CSR[0] & AT91C_UDP_TXCOMP)) |
275 | ; |
276 | |
277 | AT91C_BASE_UDP->UDP_CSR[0] &= ~AT91C_UDP_TXCOMP; |
278 | |
279 | while(AT91C_BASE_UDP->UDP_CSR[0] & AT91C_UDP_TXCOMP) |
280 | ; |
281 | } |
282 | |
283 | static void UsbSendStall(void) |
284 | { |
285 | AT91C_BASE_UDP->UDP_CSR[0] |= AT91C_UDP_FORCESTALL; |
286 | |
287 | while(!(AT91C_BASE_UDP->UDP_CSR[0] & AT91C_UDP_STALLSENT)) |
288 | ; |
289 | |
290 | AT91C_BASE_UDP->UDP_CSR[0] &= ~AT91C_UDP_STALLSENT; |
291 | |
292 | while(AT91C_BASE_UDP->UDP_CSR[0] & AT91C_UDP_STALLSENT) |
293 | ; |
294 | } |
295 | |
296 | static void HandleRxdSetupData(void) |
297 | { |
298 | int i; |
299 | UsbSetupData usd; |
300 | |
301 | for(i = 0; i < sizeof(usd); i++) { |
f7e3ed82 |
302 | ((uint8_t *)&usd)[i] = AT91C_BASE_UDP->UDP_FDR[0]; |
fdcc61d3 |
303 | } |
304 | |
305 | if(usd.bmRequestType & 0x80) { |
306 | AT91C_BASE_UDP->UDP_CSR[0] |= AT91C_UDP_DIR; |
307 | while(!(AT91C_BASE_UDP->UDP_CSR[0] & AT91C_UDP_DIR)) |
308 | ; |
309 | } |
310 | |
311 | AT91C_BASE_UDP->UDP_CSR[0] &= ~AT91C_UDP_RXSETUP; |
312 | while(AT91C_BASE_UDP->UDP_CSR[0] & AT91C_UDP_RXSETUP) |
313 | ; |
314 | |
315 | switch(usd.bRequest) { |
316 | case USB_REQUEST_GET_DESCRIPTOR: |
317 | if((usd.wValue >> 8) == USB_DESCRIPTOR_TYPE_DEVICE) { |
f7e3ed82 |
318 | UsbSendEp0((uint8_t *)&DeviceDescriptor, |
fdcc61d3 |
319 | min(sizeof(DeviceDescriptor), usd.wLength)); |
320 | } else if((usd.wValue >> 8) == USB_DESCRIPTOR_TYPE_CONFIGURATION) { |
f7e3ed82 |
321 | UsbSendEp0((uint8_t *)&ConfigurationDescriptor, |
fdcc61d3 |
322 | min(sizeof(ConfigurationDescriptor), usd.wLength)); |
323 | } else if((usd.wValue >> 8) == USB_DESCRIPTOR_TYPE_STRING) { |
f7e3ed82 |
324 | const uint8_t *s = StringDescriptors[usd.wValue & 0xff]; |
fdcc61d3 |
325 | UsbSendEp0(s, min(s[0], usd.wLength)); |
326 | } else if((usd.wValue >> 8) == USB_DESCRIPTOR_TYPE_HID_REPORT) { |
f7e3ed82 |
327 | UsbSendEp0((uint8_t *)&HidReportDescriptor, |
fdcc61d3 |
328 | min(sizeof(HidReportDescriptor), usd.wLength)); |
329 | } else { |
f7e3ed82 |
330 | *((uint32_t *)0x00200000) = usd.wValue; |
fdcc61d3 |
331 | } |
332 | break; |
333 | |
334 | case USB_REQUEST_SET_ADDRESS: |
335 | UsbSendZeroLength(); |
336 | AT91C_BASE_UDP->UDP_FADDR = AT91C_UDP_FEN | usd.wValue ; |
337 | if(usd.wValue != 0) { |
338 | AT91C_BASE_UDP->UDP_GLBSTATE = AT91C_UDP_FADDEN; |
339 | } else { |
340 | AT91C_BASE_UDP->UDP_GLBSTATE = 0; |
341 | } |
342 | break; |
343 | |
344 | case USB_REQUEST_GET_CONFIGURATION: |
345 | UsbSendEp0(&CurrentConfiguration, sizeof(CurrentConfiguration)); |
346 | break; |
347 | |
348 | case USB_REQUEST_GET_STATUS: { |
349 | if(usd.bmRequestType & 0x80) { |
f7e3ed82 |
350 | uint16_t w = 0; |
351 | UsbSendEp0((uint8_t *)&w, sizeof(w)); |
fdcc61d3 |
352 | } |
353 | break; |
354 | } |
355 | case USB_REQUEST_SET_CONFIGURATION: |
356 | CurrentConfiguration = usd.wValue; |
357 | if(CurrentConfiguration) { |
358 | AT91C_BASE_UDP->UDP_GLBSTATE = AT91C_UDP_CONFG; |
359 | AT91C_BASE_UDP->UDP_CSR[1] = AT91C_UDP_EPEDS | |
360 | AT91C_UDP_EPTYPE_INT_OUT; |
361 | AT91C_BASE_UDP->UDP_CSR[2] = AT91C_UDP_EPEDS | |
362 | AT91C_UDP_EPTYPE_INT_IN; |
363 | } else { |
364 | AT91C_BASE_UDP->UDP_GLBSTATE = AT91C_UDP_FADDEN; |
365 | AT91C_BASE_UDP->UDP_CSR[1] = 0; |
366 | AT91C_BASE_UDP->UDP_CSR[2] = 0; |
367 | } |
368 | UsbSendZeroLength(); |
369 | break; |
370 | |
371 | case USB_REQUEST_GET_INTERFACE: { |
f7e3ed82 |
372 | uint8_t b = 0; |
fdcc61d3 |
373 | UsbSendEp0(&b, sizeof(b)); |
374 | break; |
375 | } |
376 | |
377 | case USB_REQUEST_SET_INTERFACE: |
378 | UsbSendZeroLength(); |
379 | break; |
380 | |
381 | case USB_REQUEST_CLEAR_FEATURE: |
382 | case USB_REQUEST_SET_FEATURE: |
383 | UsbSendStall(); |
384 | break; |
385 | case USB_REQUEST_SET_DESCRIPTOR: |
386 | case USB_REQUEST_SYNC_FRAME: |
387 | default: |
388 | break; |
389 | } |
390 | } |
391 | |
f7e3ed82 |
392 | void UsbSendPacket(uint8_t *packet, int len) |
fdcc61d3 |
393 | { |
394 | int i, thisTime; |
395 | |
396 | while(len > 0) { |
397 | thisTime = min(len, 8); |
398 | |
399 | for(i = 0; i < thisTime; i++) { |
400 | AT91C_BASE_UDP->UDP_FDR[2] = packet[i]; |
401 | } |
402 | AT91C_BASE_UDP->UDP_CSR[2] |= AT91C_UDP_TXPKTRDY; |
403 | |
d19929cb |
404 | while(!(AT91C_BASE_UDP->UDP_CSR[2] & AT91C_UDP_TXCOMP)) { |
405 | WDT_HIT(); |
406 | } |
407 | |
fdcc61d3 |
408 | AT91C_BASE_UDP->UDP_CSR[2] &= ~AT91C_UDP_TXCOMP; |
409 | |
d19929cb |
410 | while(AT91C_BASE_UDP->UDP_CSR[2] & AT91C_UDP_TXCOMP) { |
411 | WDT_HIT(); |
412 | } |
fdcc61d3 |
413 | |
414 | len -= thisTime; |
415 | packet += thisTime; |
416 | } |
417 | } |
418 | |
419 | static void HandleRxdData(void) |
420 | { |
421 | int i, len; |
422 | |
423 | if(AT91C_BASE_UDP->UDP_CSR[1] & AT91C_UDP_RX_DATA_BK0) { |
424 | len = UDP_CSR_BYTES_RECEIVED(AT91C_BASE_UDP->UDP_CSR[1]); |
425 | |
426 | for(i = 0; i < len; i++) { |
427 | UsbBuffer[UsbSoFarCount] = AT91C_BASE_UDP->UDP_FDR[1]; |
428 | UsbSoFarCount++; |
429 | } |
430 | |
431 | AT91C_BASE_UDP->UDP_CSR[1] &= ~AT91C_UDP_RX_DATA_BK0; |
d19929cb |
432 | while(AT91C_BASE_UDP->UDP_CSR[1] & AT91C_UDP_RX_DATA_BK0) { |
433 | WDT_HIT(); |
434 | } |
fdcc61d3 |
435 | |
436 | if(UsbSoFarCount >= 64) { |
437 | UsbPacketReceived(UsbBuffer, UsbSoFarCount); |
438 | UsbSoFarCount = 0; |
439 | } |
440 | } |
441 | |
442 | if(AT91C_BASE_UDP->UDP_CSR[1] & AT91C_UDP_RX_DATA_BK1) { |
443 | len = UDP_CSR_BYTES_RECEIVED(AT91C_BASE_UDP->UDP_CSR[1]); |
444 | |
445 | for(i = 0; i < len; i++) { |
446 | UsbBuffer[UsbSoFarCount] = AT91C_BASE_UDP->UDP_FDR[1]; |
447 | UsbSoFarCount++; |
448 | } |
449 | |
450 | AT91C_BASE_UDP->UDP_CSR[1] &= ~AT91C_UDP_RX_DATA_BK1; |
d19929cb |
451 | while(AT91C_BASE_UDP->UDP_CSR[1] & AT91C_UDP_RX_DATA_BK1) { |
452 | WDT_HIT(); |
453 | } |
454 | |
fdcc61d3 |
455 | if(UsbSoFarCount >= 64) { |
456 | UsbPacketReceived(UsbBuffer, UsbSoFarCount); |
457 | UsbSoFarCount = 0; |
458 | } |
459 | } |
d19929cb |
460 | |
461 | WDT_HIT(); |
fdcc61d3 |
462 | } |
463 | |
464 | void UsbStart(void) |
465 | { |
466 | volatile int i; |
467 | |
468 | UsbSoFarCount = 0; |
469 | |
470 | USB_D_PLUS_PULLUP_OFF(); |
471 | |
472 | for(i = 0; i < 1000000; i++) |
473 | ; |
474 | |
475 | USB_D_PLUS_PULLUP_ON(); |
476 | |
477 | if(AT91C_BASE_UDP->UDP_ISR & AT91C_UDP_ENDBUSRES) { |
478 | AT91C_BASE_UDP->UDP_ICR = AT91C_UDP_ENDBUSRES; |
479 | } |
480 | } |
481 | |
f7e3ed82 |
482 | int UsbConnected() |
fdcc61d3 |
483 | { |
484 | if (AT91C_BASE_UDP->UDP_GLBSTATE & AT91C_UDP_CONFG) |
485 | return TRUE; |
486 | else |
487 | return FALSE; |
488 | } |
489 | |
f7e3ed82 |
490 | int UsbPoll(int blinkLeds) |
fdcc61d3 |
491 | { |
f7e3ed82 |
492 | int ret = FALSE; |
fdcc61d3 |
493 | |
494 | if(AT91C_BASE_UDP->UDP_ISR & AT91C_UDP_ENDBUSRES) { |
495 | AT91C_BASE_UDP->UDP_ICR = AT91C_UDP_ENDBUSRES; |
496 | |
497 | // following a reset we should be ready to receive a setup packet |
498 | AT91C_BASE_UDP->UDP_RSTEP = 0xf; |
499 | AT91C_BASE_UDP->UDP_RSTEP = 0; |
500 | |
501 | AT91C_BASE_UDP->UDP_FADDR = AT91C_UDP_FEN; |
502 | |
503 | AT91C_BASE_UDP->UDP_CSR[0] = AT91C_UDP_EPTYPE_CTRL | AT91C_UDP_EPEDS; |
504 | |
505 | CurrentConfiguration = 0; |
506 | |
507 | ret = TRUE; |
508 | } |
509 | |
510 | if(AT91C_BASE_UDP->UDP_ISR & UDP_INTERRUPT_ENDPOINT(0)) { |
511 | if(AT91C_BASE_UDP->UDP_CSR[0] & AT91C_UDP_RXSETUP) { |
512 | HandleRxdSetupData(); |
513 | ret = TRUE; |
514 | } |
515 | } |
516 | |
517 | if(AT91C_BASE_UDP->UDP_ISR & UDP_INTERRUPT_ENDPOINT(1)) { |
518 | HandleRxdData(); |
519 | ret = TRUE; |
520 | } |
521 | |
522 | return ret; |
523 | } |