]> git.zerfleddert.de Git - proxmark3-svn/blob - common/usb_cdc.c
3553d850de660eef3e865cd2a9e6ec4aaad2aea2
[proxmark3-svn] / common / usb_cdc.c
1 /*
2 * at91sam7s USB CDC device implementation
3 *
4 * Copyright (c) 2012, Roel Verdult
5 * All rights reserved.
6 *
7 * Redistribution and use in source and binary forms, with or without
8 * modification, are permitted provided that the following conditions are met:
9 * 1. Redistributions of source code must retain the above copyright
10 * notice, this list of conditions and the following disclaimer.
11 * 2. Redistributions in binary form must reproduce the above copyright
12 * notice, this list of conditions and the following disclaimer in the
13 * documentation and/or other materials provided with the distribution.
14 * 3. Neither the name of the copyright holders nor the
15 * names of its contributors may be used to endorse or promote products
16 * derived from this software without specific prior written permission.
17 *
18 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS ''AS IS'' AND ANY
19 * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
20 * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
21 * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDERS BE LIABLE FOR ANY
22 * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
23 * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
24 * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
25 * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
26 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
27 * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
28 *
29 * based on the "Basic USB Example" from ATMEL (doc6123.pdf)
30 *
31 * @file usb_cdc.c
32 * @brief
33 */
34
35 #include "usb_cdc.h"
36 #include "at91sam7s512.h"
37 #include "config_gpio.h"
38
39
40 #define AT91C_EP_CONTROL 0
41 #define AT91C_EP_OUT 1
42 #define AT91C_EP_IN 2
43 #define AT91C_EP_NOTIFY 3
44 #define AT91C_EP_OUT_SIZE 0x40
45 #define AT91C_EP_IN_SIZE 0x40
46
47 // Language must always be 0.
48 #define STR_LANGUAGE_CODES 0x00
49 #define STR_MANUFACTURER 0x01
50 #define STR_PRODUCT 0x02
51
52 static const char devDescriptor[] = {
53 /* Device descriptor */
54 0x12, // bLength
55 0x01, // bDescriptorType
56 0x00,0x02, // Complies with USB Spec. Release (0200h = release 2.0)
57 0x02, // bDeviceClass: (Communication Device Class)
58 0x00, // bDeviceSubclass: (unused at this time)
59 0x00, // bDeviceProtocol: (unused at this time)
60 0x08, // bMaxPacketSize0
61 0xc4,0x9a, // Vendor ID (0x9ac4 = J. Westhues)
62 0x8f,0x4b, // Product ID (0x4b8f = Proxmark-3 RFID Instrument)
63 0x01,0x00, // Device release number (0001)
64 STR_MANUFACTURER, // iManufacturer
65 STR_PRODUCT, // iProduct
66 0x00, // iSerialNumber
67 0x01 // bNumConfigs
68 };
69
70 static const char cfgDescriptor[] = {
71 /* ============== CONFIGURATION 1 =========== */
72 /* Configuration 1 descriptor */
73 0x09, // CbLength
74 0x02, // CbDescriptorType
75 0x43, // CwTotalLength 2 EP + Control
76 0x00,
77 0x02, // CbNumInterfaces
78 0x01, // CbConfigurationValue
79 0x00, // CiConfiguration
80 0x80, // CbmAttributes (Bus Powered)
81 0x4B, // CMaxPower (150mA max current drawn from bus)
82
83 /* Interface 0 Descriptor: Communication Class Interface */
84 0x09, // bLength
85 0x04, // bDescriptorType
86 0x00, // bInterfaceNumber
87 0x00, // bAlternateSetting
88 0x01, // bNumEndpoints
89 0x02, // bInterfaceClass: Communication Interface Class
90 0x02, // bInterfaceSubclass: Abstract Control Model
91 0x01, // bInterfaceProtocol: Common AT Commands, V.25ter
92 0x00, // iInterface
93
94 /* Header Functional Descriptor */
95 0x05, // bFunction Length
96 0x24, // bDescriptor type: CS_INTERFACE
97 0x00, // bDescriptor subtype: Header Functional Descriptor
98 0x10, // bcdCDC:1.1
99 0x01,
100
101 /* ACM Functional Descriptor */
102 0x04, // bFunctionLength
103 0x24, // bDescriptor Type: CS_INTERFACE
104 0x02, // bDescriptor Subtype: Abstract Control Management Functional Descriptor
105 0x02, // bmCapabilities: D1: Device supports the request combination of Set_Line_Coding, Set_Control_Line_State, Get_Line_Coding, and the notification Serial_State
106
107 /* Union Functional Descriptor */
108 0x05, // bFunctionLength
109 0x24, // bDescriptorType: CS_INTERFACE
110 0x06, // bDescriptor Subtype: Union Functional Descriptor
111 0x00, // bMasterInterface: Communication Class Interface
112 0x01, // bSlaveInterface0: Data Class Interface
113
114 /* Call Management Functional Descriptor */
115 0x05, // bFunctionLength
116 0x24, // bDescriptor Type: CS_INTERFACE
117 0x01, // bDescriptor Subtype: Call Management Functional Descriptor
118 0x00, // bmCapabilities: Device sends/receives call management information only over the Communication Class interface. Device does not handle call management itself
119 0x01, // bDataInterface: Data Class Interface 1
120
121 /* Endpoint 1 descriptor */
122 0x07, // bLength
123 0x05, // bDescriptorType
124 0x83, // bEndpointAddress: Endpoint 03 - IN
125 0x03, // bmAttributes: INT
126 0x08, // wMaxPacketSize: 8
127 0x00,
128 0xFF, // bInterval
129
130 /* Interface 1 Descriptor: Data Class Interface */
131 0x09, // bLength
132 0x04, // bDescriptorType
133 0x01, // bInterfaceNumber
134 0x00, // bAlternateSetting
135 0x02, // bNumEndpoints
136 0x0A, // bInterfaceClass: Data Interface Class
137 0x00, // bInterfaceSubclass: not used
138 0x00, // bInterfaceProtocol: No class specific protocol required)
139 0x00, // iInterface
140
141 /* Endpoint 1 descriptor */
142 0x07, // bLength
143 0x05, // bDescriptorType
144 0x01, // bEndpointAddress: Endpoint 01 - OUT
145 0x02, // bmAttributes: BULK
146 AT91C_EP_OUT_SIZE, // wMaxPacketSize
147 0x00,
148 0x00, // bInterval
149
150 /* Endpoint 2 descriptor */
151 0x07, // bLength
152 0x05, // bDescriptorType
153 0x82, // bEndpointAddress: Endpoint 02 - IN
154 0x02, // bmAttributes: BULK
155 AT91C_EP_IN_SIZE, // wMaxPacketSize
156 0x00,
157 0x00 // bInterval
158 };
159
160 static const char StrDescLanguageCodes[] = {
161 4, // Length
162 0x03, // Type is string
163 0x09, 0x04 // supported language Code 0 = 0x0409 (English)
164 };
165
166 // Note: ModemManager (Linux) ignores Proxmark3 devices by matching the
167 // manufacturer string "proxmark.org". Don't change this.
168 static const char StrDescManufacturer[] = {
169 26, // 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 'o', 0x00,
181 'r', 0x00,
182 'g', 0x00
183 };
184
185 static const char StrDescProduct[] = {
186 8, // Length
187 0x03, // Type is string
188 'P', 0x00,
189 'M', 0x00,
190 '3', 0x00
191 };
192
193 const char* getStringDescriptor(uint8_t idx)
194 {
195 switch (idx) {
196 case STR_LANGUAGE_CODES:
197 return StrDescLanguageCodes;
198 case STR_MANUFACTURER:
199 return StrDescManufacturer;
200 case STR_PRODUCT:
201 return StrDescProduct;
202 default:
203 return NULL;
204 }
205 }
206
207 // Bitmap for all status bits in CSR which must be written as 1 to cause no effect
208 #define REG_NO_EFFECT_1_ALL AT91C_UDP_RX_DATA_BK0 | AT91C_UDP_RX_DATA_BK1 \
209 |AT91C_UDP_STALLSENT | AT91C_UDP_RXSETUP \
210 |AT91C_UDP_TXCOMP
211
212 // Clear flags in the UDP_CSR register
213 #define UDP_CLEAR_EP_FLAGS(endpoint, flags) { \
214 volatile unsigned int reg; \
215 reg = pUdp->UDP_CSR[(endpoint)]; \
216 reg |= REG_NO_EFFECT_1_ALL; \
217 reg &= ~(flags); \
218 pUdp->UDP_CSR[(endpoint)] = reg; \
219 }
220
221 // Set flags in the UDP_CSR register
222 #define UDP_SET_EP_FLAGS(endpoint, flags) { \
223 volatile unsigned int reg; \
224 reg = pUdp->UDP_CSR[(endpoint)]; \
225 reg |= REG_NO_EFFECT_1_ALL; \
226 reg |= (flags); \
227 pUdp->UDP_CSR[(endpoint)] = reg; \
228 }
229
230 /* USB standard request codes */
231 #define STD_GET_STATUS_ZERO 0x0080
232 #define STD_GET_STATUS_INTERFACE 0x0081
233 #define STD_GET_STATUS_ENDPOINT 0x0082
234
235 #define STD_CLEAR_FEATURE_ZERO 0x0100
236 #define STD_CLEAR_FEATURE_INTERFACE 0x0101
237 #define STD_CLEAR_FEATURE_ENDPOINT 0x0102
238
239 #define STD_SET_FEATURE_ZERO 0x0300
240 #define STD_SET_FEATURE_INTERFACE 0x0301
241 #define STD_SET_FEATURE_ENDPOINT 0x0302
242
243 #define STD_SET_ADDRESS 0x0500
244 #define STD_GET_DESCRIPTOR 0x0680
245 #define STD_SET_DESCRIPTOR 0x0700
246 #define STD_GET_CONFIGURATION 0x0880
247 #define STD_SET_CONFIGURATION 0x0900
248 #define STD_GET_INTERFACE 0x0A81
249 #define STD_SET_INTERFACE 0x0B01
250 #define STD_SYNCH_FRAME 0x0C82
251
252 /* CDC Class Specific Request Code */
253 #define GET_LINE_CODING 0x21A1
254 #define SET_LINE_CODING 0x2021
255 #define SET_CONTROL_LINE_STATE 0x2221
256
257 typedef struct {
258 unsigned int dwDTERRate;
259 char bCharFormat;
260 char bParityType;
261 char bDataBits;
262 } AT91S_CDC_LINE_CODING, *AT91PS_CDC_LINE_CODING;
263
264 AT91S_CDC_LINE_CODING line = {
265 115200, // baudrate
266 0, // 1 Stop Bit
267 0, // None Parity
268 8}; // 8 Data bits
269
270
271 void AT91F_CDC_Enumerate();
272
273 AT91PS_UDP pUdp = AT91C_BASE_UDP;
274 byte_t btConfiguration = 0;
275 byte_t btConnection = 0;
276 byte_t btReceiveBank = AT91C_UDP_RX_DATA_BK0;
277
278
279 //*----------------------------------------------------------------------------
280 //* \fn usb_disable
281 //* \brief This function deactivates the USB device
282 //*----------------------------------------------------------------------------
283 void usb_disable() {
284 // Disconnect the USB device
285 AT91C_BASE_PIOA->PIO_ODR = GPIO_USB_PU;
286
287 // Clear all lingering interrupts
288 if(pUdp->UDP_ISR & AT91C_UDP_ENDBUSRES) {
289 pUdp->UDP_ICR = AT91C_UDP_ENDBUSRES;
290 }
291 }
292
293
294 //*----------------------------------------------------------------------------
295 //* \fn usb_enable
296 //* \brief This function Activates the USB device
297 //*----------------------------------------------------------------------------
298 void usb_enable() {
299 // Set the PLL USB Divider
300 AT91C_BASE_CKGR->CKGR_PLLR |= AT91C_CKGR_USBDIV_1 ;
301
302 // Specific Chip USB Initialisation
303 // Enables the 48MHz USB clock UDPCK and System Peripheral USB Clock
304 AT91C_BASE_PMC->PMC_SCER = AT91C_PMC_UDP;
305 AT91C_BASE_PMC->PMC_PCER = (1 << AT91C_ID_UDP);
306
307 // Enable UDP PullUp (USB_DP_PUP) : enable & Clear of the corresponding PIO
308 // Set in PIO mode and Configure in Output
309 AT91C_BASE_PIOA->PIO_PER = GPIO_USB_PU; // Set in PIO mode
310 AT91C_BASE_PIOA->PIO_OER = GPIO_USB_PU; // Configure as Output
311
312 // Clear for set the Pullup resistor
313 AT91C_BASE_PIOA->PIO_CODR = GPIO_USB_PU;
314
315 // Disconnect and reconnect USB controller for 100ms
316 usb_disable();
317
318 // Wait for a short while
319 for (volatile size_t i=0; i<0x100000; i++);
320
321 // Reconnect USB reconnect
322 AT91C_BASE_PIOA->PIO_SODR = GPIO_USB_PU;
323 AT91C_BASE_PIOA->PIO_OER = GPIO_USB_PU;
324 }
325
326
327 //*----------------------------------------------------------------------------
328 //* \fn usb_check
329 //* \brief Test if the device is configured and handle enumeration
330 //*----------------------------------------------------------------------------
331 bool usb_check() {
332 AT91_REG isr = pUdp->UDP_ISR;
333
334 if (isr & AT91C_UDP_ENDBUSRES) {
335 pUdp->UDP_ICR = AT91C_UDP_ENDBUSRES;
336 // reset all endpoints
337 pUdp->UDP_RSTEP = (unsigned int)-1;
338 pUdp->UDP_RSTEP = 0;
339 // Enable the function
340 pUdp->UDP_FADDR = AT91C_UDP_FEN;
341 // Configure endpoint 0
342 pUdp->UDP_CSR[AT91C_EP_CONTROL] = (AT91C_UDP_EPEDS | AT91C_UDP_EPTYPE_CTRL);
343 } else if (isr & AT91C_UDP_EPINT0) {
344 pUdp->UDP_ICR = AT91C_UDP_EPINT0;
345 AT91F_CDC_Enumerate();
346 }
347 return (btConfiguration) ? true : false;
348 }
349
350
351 bool usb_poll()
352 {
353 if (!usb_check()) return false;
354 return (pUdp->UDP_CSR[AT91C_EP_OUT] & btReceiveBank);
355 }
356
357
358 /**
359 In github PR #129, some users appears to get a false positive from
360 usb_poll, which returns true, but the usb_read operation
361 still returns 0.
362 This check is basically the same as above, but also checks
363 that the length available to read is non-zero, thus hopefully fixes the
364 bug.
365 **/
366 bool usb_poll_validate_length()
367 {
368 if (!usb_check()) return false;
369 if (!(pUdp->UDP_CSR[AT91C_EP_OUT] & btReceiveBank)) return false;
370 return (pUdp->UDP_CSR[AT91C_EP_OUT] >> 16) > 0;
371 }
372
373 //*----------------------------------------------------------------------------
374 //* \fn usb_read
375 //* \brief Read available data from Endpoint OUT
376 //*----------------------------------------------------------------------------
377 uint32_t usb_read(byte_t* data, size_t len) {
378 byte_t bank = btReceiveBank;
379 uint32_t packetSize, nbBytesRcv = 0;
380 uint32_t time_out = 0;
381
382 while (len) {
383 if (!usb_check()) break;
384
385 if ( pUdp->UDP_CSR[AT91C_EP_OUT] & bank ) {
386 packetSize = MIN(pUdp->UDP_CSR[AT91C_EP_OUT] >> 16, len);
387 len -= packetSize;
388 while(packetSize--)
389 data[nbBytesRcv++] = pUdp->UDP_FDR[AT91C_EP_OUT];
390 UDP_CLEAR_EP_FLAGS(AT91C_EP_OUT, bank);
391 if (bank == AT91C_UDP_RX_DATA_BK0) {
392 bank = AT91C_UDP_RX_DATA_BK1;
393 } else {
394 bank = AT91C_UDP_RX_DATA_BK0;
395 }
396 }
397 if (time_out++ == 0x1fff) break;
398 }
399
400 btReceiveBank = bank;
401 return nbBytesRcv;
402 }
403
404
405 //*----------------------------------------------------------------------------
406 //* \fn usb_write
407 //* \brief Send through endpoint 2
408 //*----------------------------------------------------------------------------
409 uint32_t usb_write(const byte_t* data, const size_t len) {
410 size_t length = len;
411 uint32_t cpt = 0;
412
413 if (!length) return 0;
414 if (!usb_check()) return 0;
415
416 // Send the first packet
417 cpt = MIN(length, AT91C_EP_IN_SIZE);
418 length -= cpt;
419 while (cpt--) {
420 pUdp->UDP_FDR[AT91C_EP_IN] = *data++;
421 }
422 UDP_SET_EP_FLAGS(AT91C_EP_IN, AT91C_UDP_TXPKTRDY);
423
424 while (length) {
425 // Fill the next bank
426 cpt = MIN(length, AT91C_EP_IN_SIZE);
427 length -= cpt;
428 while (cpt--) {
429 pUdp->UDP_FDR[AT91C_EP_IN] = *data++;
430 }
431 // Wait for the previous bank to be sent
432 while (!(pUdp->UDP_CSR[AT91C_EP_IN] & AT91C_UDP_TXCOMP)) {
433 if (!usb_check()) return length;
434 }
435 UDP_CLEAR_EP_FLAGS(AT91C_EP_IN, AT91C_UDP_TXCOMP);
436 while (pUdp->UDP_CSR[AT91C_EP_IN] & AT91C_UDP_TXCOMP);
437 UDP_SET_EP_FLAGS(AT91C_EP_IN, AT91C_UDP_TXPKTRDY);
438 }
439
440 // Wait for the end of transfer
441 while (!(pUdp->UDP_CSR[AT91C_EP_IN] & AT91C_UDP_TXCOMP)) {
442 if (!usb_check()) return length;
443 }
444
445 UDP_CLEAR_EP_FLAGS(AT91C_EP_IN, AT91C_UDP_TXCOMP);
446 while (pUdp->UDP_CSR[AT91C_EP_IN] & AT91C_UDP_TXCOMP);
447
448 return length;
449 }
450
451
452 //*----------------------------------------------------------------------------
453 //* \fn AT91F_USB_SendData
454 //* \brief Send Data through the control endpoint
455 //*----------------------------------------------------------------------------
456 unsigned int csrTab[100] = {0x00};
457 unsigned char csrIdx = 0;
458
459 static void AT91F_USB_SendData(AT91PS_UDP pUdp, const char *pData, uint32_t length) {
460 uint32_t cpt = 0;
461 AT91_REG csr;
462
463 do {
464 cpt = MIN(length, 8);
465 length -= cpt;
466
467 while (cpt--)
468 pUdp->UDP_FDR[0] = *pData++;
469
470 if (pUdp->UDP_CSR[AT91C_EP_CONTROL] & AT91C_UDP_TXCOMP) {
471 UDP_CLEAR_EP_FLAGS(AT91C_EP_CONTROL, AT91C_UDP_TXCOMP);
472 while (pUdp->UDP_CSR[AT91C_EP_CONTROL] & AT91C_UDP_TXCOMP);
473 }
474
475 UDP_SET_EP_FLAGS(AT91C_EP_CONTROL, AT91C_UDP_TXPKTRDY);
476 do {
477 csr = pUdp->UDP_CSR[AT91C_EP_CONTROL];
478
479 // Data IN stage has been stopped by a status OUT
480 if (csr & AT91C_UDP_RX_DATA_BK0) {
481 UDP_CLEAR_EP_FLAGS(AT91C_EP_CONTROL, AT91C_UDP_RX_DATA_BK0);
482 return;
483 }
484 } while ( !(csr & AT91C_UDP_TXCOMP) );
485
486 } while (length);
487
488 if (pUdp->UDP_CSR[AT91C_EP_CONTROL] & AT91C_UDP_TXCOMP) {
489 UDP_CLEAR_EP_FLAGS(AT91C_EP_CONTROL, AT91C_UDP_TXCOMP);
490 while (pUdp->UDP_CSR[AT91C_EP_CONTROL] & AT91C_UDP_TXCOMP);
491 }
492 }
493
494
495 //*----------------------------------------------------------------------------
496 //* \fn AT91F_USB_SendZlp
497 //* \brief Send zero length packet through the control endpoint
498 //*----------------------------------------------------------------------------
499 void AT91F_USB_SendZlp(AT91PS_UDP pUdp) {
500 UDP_SET_EP_FLAGS(AT91C_EP_CONTROL, AT91C_UDP_TXPKTRDY);
501 while ( !(pUdp->UDP_CSR[AT91C_EP_CONTROL] & AT91C_UDP_TXCOMP) );
502 UDP_CLEAR_EP_FLAGS(AT91C_EP_CONTROL, AT91C_UDP_TXCOMP);
503 while (pUdp->UDP_CSR[AT91C_EP_CONTROL] & AT91C_UDP_TXCOMP);
504 }
505
506
507 //*----------------------------------------------------------------------------
508 //* \fn AT91F_USB_SendStall
509 //* \brief Stall the control endpoint
510 //*----------------------------------------------------------------------------
511 void AT91F_USB_SendStall(AT91PS_UDP pUdp) {
512 UDP_SET_EP_FLAGS(AT91C_EP_CONTROL, AT91C_UDP_FORCESTALL);
513 while ( !(pUdp->UDP_CSR[AT91C_EP_CONTROL] & AT91C_UDP_ISOERROR) );
514 UDP_CLEAR_EP_FLAGS(AT91C_EP_CONTROL, AT91C_UDP_FORCESTALL | AT91C_UDP_ISOERROR);
515 while (pUdp->UDP_CSR[AT91C_EP_CONTROL] & (AT91C_UDP_FORCESTALL | AT91C_UDP_ISOERROR));
516 }
517
518
519 //*----------------------------------------------------------------------------
520 //* \fn AT91F_CDC_Enumerate
521 //* \brief This function is a callback invoked when a SETUP packet is received
522 //*----------------------------------------------------------------------------
523 void AT91F_CDC_Enumerate() {
524 byte_t bmRequestType, bRequest;
525 uint16_t wValue, wIndex, wLength, wStatus;
526
527 if ( !(pUdp->UDP_CSR[AT91C_EP_CONTROL] & AT91C_UDP_RXSETUP) )
528 return;
529
530 bmRequestType = pUdp->UDP_FDR[AT91C_EP_CONTROL];
531 bRequest = pUdp->UDP_FDR[AT91C_EP_CONTROL];
532 wValue = (pUdp->UDP_FDR[AT91C_EP_CONTROL] & 0xFF);
533 wValue |= (pUdp->UDP_FDR[AT91C_EP_CONTROL] << 8);
534 wIndex = (pUdp->UDP_FDR[AT91C_EP_CONTROL] & 0xFF);
535 wIndex |= (pUdp->UDP_FDR[AT91C_EP_CONTROL] << 8);
536 wLength = (pUdp->UDP_FDR[AT91C_EP_CONTROL] & 0xFF);
537 wLength |= (pUdp->UDP_FDR[AT91C_EP_CONTROL] << 8);
538
539 if (bmRequestType & 0x80) { // Data Phase Transfer Direction Device to Host
540 UDP_SET_EP_FLAGS(AT91C_EP_CONTROL, AT91C_UDP_DIR);
541 while ( !(pUdp->UDP_CSR[AT91C_EP_CONTROL] & AT91C_UDP_DIR) );
542 }
543 UDP_CLEAR_EP_FLAGS(AT91C_EP_CONTROL, AT91C_UDP_RXSETUP);
544 while ( (pUdp->UDP_CSR[AT91C_EP_CONTROL] & AT91C_UDP_RXSETUP) );
545
546 // Handle supported standard device request Cf Table 9-3 in USB specification Rev 1.1
547 switch ((bRequest << 8) | bmRequestType) {
548 case STD_GET_DESCRIPTOR:
549 if (wValue == 0x100) // Return Device Descriptor
550 AT91F_USB_SendData(pUdp, devDescriptor, MIN(sizeof(devDescriptor), wLength));
551 else if (wValue == 0x200) // Return Configuration Descriptor
552 AT91F_USB_SendData(pUdp, cfgDescriptor, MIN(sizeof(cfgDescriptor), wLength));
553 else if ((wValue & 0x300) == 0x300) // Return Manufacturer Descriptor - this is needed by Android
554 AT91F_USB_SendData(pUdp, StrDescManufacturer, MIN(sizeof(StrDescManufacturer), wLength));
555 else if ((wValue & 0xF00) == 0x300) { // Return String Descriptor
556 const char *strDescriptor = getStringDescriptor(wValue & 0xff);
557 if (strDescriptor != NULL) {
558 AT91F_USB_SendData(pUdp, strDescriptor, MIN(strDescriptor[0], wLength));
559 } else {
560 AT91F_USB_SendStall(pUdp);
561 }
562 }
563 else
564 AT91F_USB_SendStall(pUdp);
565 break;
566 case STD_SET_ADDRESS:
567 AT91F_USB_SendZlp(pUdp);
568 pUdp->UDP_FADDR = (AT91C_UDP_FEN | wValue);
569 pUdp->UDP_GLBSTATE = (wValue) ? AT91C_UDP_FADDEN : 0;
570 break;
571 case STD_SET_CONFIGURATION:
572 btConfiguration = wValue;
573 AT91F_USB_SendZlp(pUdp);
574 pUdp->UDP_GLBSTATE = (wValue) ? AT91C_UDP_CONFG : AT91C_UDP_FADDEN;
575 pUdp->UDP_CSR[AT91C_EP_OUT] = (wValue) ? (AT91C_UDP_EPEDS | AT91C_UDP_EPTYPE_BULK_OUT) : 0;
576 pUdp->UDP_CSR[AT91C_EP_IN] = (wValue) ? (AT91C_UDP_EPEDS | AT91C_UDP_EPTYPE_BULK_IN) : 0;
577 pUdp->UDP_CSR[AT91C_EP_NOTIFY] = (wValue) ? (AT91C_UDP_EPEDS | AT91C_UDP_EPTYPE_INT_IN) : 0;
578 break;
579 case STD_GET_CONFIGURATION:
580 AT91F_USB_SendData(pUdp, (char *) &(btConfiguration), sizeof(btConfiguration));
581 break;
582 case STD_GET_STATUS_ZERO:
583 wStatus = 0; // Device is Bus powered, remote wakeup disabled
584 AT91F_USB_SendData(pUdp, (char *) &wStatus, sizeof(wStatus));
585 break;
586 case STD_GET_STATUS_INTERFACE:
587 wStatus = 0; // reserved for future use
588 AT91F_USB_SendData(pUdp, (char *) &wStatus, sizeof(wStatus));
589 break;
590 case STD_GET_STATUS_ENDPOINT:
591 wStatus = 0;
592 wIndex &= 0x0F;
593 if ((pUdp->UDP_GLBSTATE & AT91C_UDP_CONFG) && (wIndex <= AT91C_EP_NOTIFY)) {
594 wStatus = (pUdp->UDP_CSR[wIndex] & AT91C_UDP_EPEDS) ? 0 : 1;
595 AT91F_USB_SendData(pUdp, (char *) &wStatus, sizeof(wStatus));
596 }
597 else if ((pUdp->UDP_GLBSTATE & AT91C_UDP_FADDEN) && (wIndex == AT91C_EP_CONTROL)) {
598 wStatus = (pUdp->UDP_CSR[wIndex] & AT91C_UDP_EPEDS) ? 0 : 1;
599 AT91F_USB_SendData(pUdp, (char *) &wStatus, sizeof(wStatus));
600 }
601 else
602 AT91F_USB_SendStall(pUdp);
603 break;
604 case STD_SET_FEATURE_ZERO:
605 AT91F_USB_SendStall(pUdp);
606 break;
607 case STD_SET_FEATURE_INTERFACE:
608 AT91F_USB_SendZlp(pUdp);
609 break;
610 case STD_SET_FEATURE_ENDPOINT:
611 wIndex &= 0x0F;
612 if ((wValue == 0) && (wIndex >= AT91C_EP_OUT) && (wIndex <= AT91C_EP_NOTIFY)) {
613 pUdp->UDP_CSR[wIndex] = 0;
614 AT91F_USB_SendZlp(pUdp);
615 }
616 else
617 AT91F_USB_SendStall(pUdp);
618 break;
619 case STD_CLEAR_FEATURE_ZERO:
620 AT91F_USB_SendStall(pUdp);
621 break;
622 case STD_CLEAR_FEATURE_INTERFACE:
623 AT91F_USB_SendZlp(pUdp);
624 break;
625 case STD_CLEAR_FEATURE_ENDPOINT:
626 wIndex &= 0x0F;
627 if ((wValue == 0) && (wIndex >= AT91C_EP_OUT) && (wIndex <= AT91C_EP_NOTIFY)) {
628 if (wIndex == AT91C_EP_OUT)
629 pUdp->UDP_CSR[AT91C_EP_OUT] = (AT91C_UDP_EPEDS | AT91C_UDP_EPTYPE_BULK_OUT);
630 else if (wIndex == AT91C_EP_IN)
631 pUdp->UDP_CSR[AT91C_EP_IN] = (AT91C_UDP_EPEDS | AT91C_UDP_EPTYPE_BULK_IN);
632 else if (wIndex == AT91C_EP_NOTIFY)
633 pUdp->UDP_CSR[AT91C_EP_NOTIFY] = (AT91C_UDP_EPEDS | AT91C_UDP_EPTYPE_INT_IN);
634 AT91F_USB_SendZlp(pUdp);
635 }
636 else
637 AT91F_USB_SendStall(pUdp);
638 break;
639
640 // handle CDC class requests
641 case SET_LINE_CODING:
642 while ( !(pUdp->UDP_CSR[AT91C_EP_CONTROL] & AT91C_UDP_RX_DATA_BK0) );
643 UDP_CLEAR_EP_FLAGS(AT91C_EP_CONTROL, AT91C_UDP_RX_DATA_BK0);
644 AT91F_USB_SendZlp(pUdp);
645 break;
646 case GET_LINE_CODING:
647 AT91F_USB_SendData(pUdp, (char *) &line, MIN(sizeof(line), wLength));
648 break;
649 case SET_CONTROL_LINE_STATE:
650 btConnection = wValue;
651 AT91F_USB_SendZlp(pUdp);
652 break;
653 default:
654 AT91F_USB_SendStall(pUdp);
655 break;
656 }
657 }
Impressum, Datenschutz