]> git.zerfleddert.de Git - proxmark3-svn/blob - common/usb_cdc.c
hardnested: reduce disk space for tables (by > 700MBytes) and other minor changes
[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_IN_SIZE 0x40
42 #define AT91C_EP_OUT 1
43 #define AT91C_EP_OUT_SIZE 0x40
44 #define AT91C_EP_IN 2
45
46 static const char devDescriptor[] = {
47 /* Device descriptor */
48 0x12, // bLength
49 0x01, // bDescriptorType
50 0x00,0x02, // Complies with USB Spec. Release (0200h = release 2.0)
51 0x02, // bDeviceClass: CDC class code
52 0x00, // bDeviceSubclass: CDC class sub code
53 0x00, // bDeviceProtocol: CDC Device protocol
54 0x08, // bMaxPacketSize0
55 0xc4,0x9a, // Vendor ID (0x9ac4 = J. Westhues)
56 0x8f,0x4b, // Product ID (0x4b8f = Proxmark-3 RFID Instrument)
57 0x01,0x00, // Device release number (0001)
58 0x01, // iManufacturer
59 0x02, // iProduct
60 0x00, // iSerialNumber
61 0x01 // bNumConfigs
62 };
63
64 static const char cfgDescriptor[] = {
65 /* ============== CONFIGURATION 1 =========== */
66 /* Configuration 1 descriptor */
67 0x09, // CbLength
68 0x02, // CbDescriptorType
69 0x43, // CwTotalLength 2 EP + Control
70 0x00,
71 0x02, // CbNumInterfaces
72 0x01, // CbConfigurationValue
73 0x00, // CiConfiguration
74 0xC0, // CbmAttributes 0xA0
75 0xFA, // CMaxPower
76
77 /* Communication Class Interface Descriptor Requirement */
78 0x09, // bLength
79 0x04, // bDescriptorType
80 0x00, // bInterfaceNumber
81 0x00, // bAlternateSetting
82 0x01, // bNumEndpoints
83 0x02, // bInterfaceClass
84 0x02, // bInterfaceSubclass
85 0x01, // bInterfaceProtocol
86 0x00, // iInterface
87
88 /* Header Functional Descriptor */
89 0x05, // bFunction Length
90 0x24, // bDescriptor type: CS_INTERFACE
91 0x00, // bDescriptor subtype: Header Func Desc
92 0x10, // bcdCDC:1.1
93 0x01,
94
95 /* ACM Functional Descriptor */
96 0x04, // bFunctionLength
97 0x24, // bDescriptor Type: CS_INTERFACE
98 0x02, // bDescriptor Subtype: ACM Func Desc
99 0x02, // bmCapabilities
100
101 /* Union Functional Descriptor */
102 0x05, // bFunctionLength
103 0x24, // bDescriptorType: CS_INTERFACE
104 0x06, // bDescriptor Subtype: Union Func Desc
105 0x00, // bMasterInterface: Communication Class Interface
106 0x01, // bSlaveInterface0: Data Class Interface
107
108 /* Call Management Functional Descriptor */
109 0x05, // bFunctionLength
110 0x24, // bDescriptor Type: CS_INTERFACE
111 0x01, // bDescriptor Subtype: Call Management Func Desc
112 0x00, // bmCapabilities: D1 + D0
113 0x01, // bDataInterface: Data Class Interface 1
114
115 /* Endpoint 1 descriptor */
116 0x07, // bLength
117 0x05, // bDescriptorType
118 0x83, // bEndpointAddress, Endpoint 03 - IN
119 0x03, // bmAttributes INT
120 0x08, // wMaxPacketSize
121 0x00,
122 0xFF, // bInterval
123
124 /* Data Class Interface Descriptor Requirement */
125 0x09, // bLength
126 0x04, // bDescriptorType
127 0x01, // bInterfaceNumber
128 0x00, // bAlternateSetting
129 0x02, // bNumEndpoints
130 0x0A, // bInterfaceClass
131 0x00, // bInterfaceSubclass
132 0x00, // bInterfaceProtocol
133 0x00, // iInterface
134
135 /* First alternate setting */
136 /* Endpoint 1 descriptor */
137 0x07, // bLength
138 0x05, // bDescriptorType
139 0x01, // bEndpointAddress, Endpoint 01 - OUT
140 0x02, // bmAttributes BULK
141 AT91C_EP_OUT_SIZE, // wMaxPacketSize
142 0x00,
143 0x00, // bInterval
144
145 /* Endpoint 2 descriptor */
146 0x07, // bLength
147 0x05, // bDescriptorType
148 0x82, // bEndpointAddress, Endpoint 02 - IN
149 0x02, // bmAttributes BULK
150 AT91C_EP_IN_SIZE, // wMaxPacketSize
151 0x00,
152 0x00 // bInterval
153 };
154
155 static const char StrDescLanguageCodes[] = {
156 4, // Length
157 0x03, // Type is string
158 0x09, 0x04 // supported language Code 0 = 0x0409 (English)
159 };
160
161 static const char StrDescManufacturer[] = {
162 26, // Length
163 0x03, // Type is string
164 'p', 0x00,
165 'r', 0x00,
166 'o', 0x00,
167 'x', 0x00,
168 'm', 0x00,
169 'a', 0x00,
170 'r', 0x00,
171 'k', 0x00,
172 '.', 0x00,
173 'o', 0x00,
174 'r', 0x00,
175 'g', 0x00
176 };
177
178 static const char StrDescProduct[] = {
179 8, // Length
180 0x03, // Type is string
181 'P', 0x00,
182 'M', 0x00,
183 '3', 0x00
184 };
185
186 static const char* const pStrings[] =
187 {
188 StrDescLanguageCodes,
189 StrDescManufacturer,
190 StrDescProduct
191 };
192
193 const char* getStringDescriptor(uint8_t idx)
194 {
195 if(idx >= (sizeof(pStrings) / sizeof(pStrings[0]))) {
196 return(NULL);
197 } else {
198 return(pStrings[idx]);
199 }
200 }
201
202 // Bitmap for all status bits in CSR which must be written as 1 to cause no effect
203 #define REG_NO_EFFECT_1_ALL AT91C_UDP_RX_DATA_BK0 | AT91C_UDP_RX_DATA_BK1 \
204 |AT91C_UDP_STALLSENT | AT91C_UDP_RXSETUP \
205 |AT91C_UDP_TXCOMP
206
207 // Clear flags in the UDP_CSR register
208 #define UDP_CLEAR_EP_FLAGS(endpoint, flags) { \
209 volatile unsigned int reg; \
210 reg = pUdp->UDP_CSR[(endpoint)]; \
211 reg |= REG_NO_EFFECT_1_ALL; \
212 reg &= ~(flags); \
213 pUdp->UDP_CSR[(endpoint)] = reg; \
214 }
215
216 // Set flags in the UDP_CSR register
217 #define UDP_SET_EP_FLAGS(endpoint, flags) { \
218 volatile unsigned int reg; \
219 reg = pUdp->UDP_CSR[(endpoint)]; \
220 reg |= REG_NO_EFFECT_1_ALL; \
221 reg |= (flags); \
222 pUdp->UDP_CSR[(endpoint)] = reg; \
223 }
224
225 /* USB standard request codes */
226 #define STD_GET_STATUS_ZERO 0x0080
227 #define STD_GET_STATUS_INTERFACE 0x0081
228 #define STD_GET_STATUS_ENDPOINT 0x0082
229
230 #define STD_CLEAR_FEATURE_ZERO 0x0100
231 #define STD_CLEAR_FEATURE_INTERFACE 0x0101
232 #define STD_CLEAR_FEATURE_ENDPOINT 0x0102
233
234 #define STD_SET_FEATURE_ZERO 0x0300
235 #define STD_SET_FEATURE_INTERFACE 0x0301
236 #define STD_SET_FEATURE_ENDPOINT 0x0302
237
238 #define STD_SET_ADDRESS 0x0500
239 #define STD_GET_DESCRIPTOR 0x0680
240 #define STD_SET_DESCRIPTOR 0x0700
241 #define STD_GET_CONFIGURATION 0x0880
242 #define STD_SET_CONFIGURATION 0x0900
243 #define STD_GET_INTERFACE 0x0A81
244 #define STD_SET_INTERFACE 0x0B01
245 #define STD_SYNCH_FRAME 0x0C82
246
247 /* CDC Class Specific Request Code */
248 #define GET_LINE_CODING 0x21A1
249 #define SET_LINE_CODING 0x2021
250 #define SET_CONTROL_LINE_STATE 0x2221
251
252 typedef struct {
253 unsigned int dwDTERRate;
254 char bCharFormat;
255 char bParityType;
256 char bDataBits;
257 } AT91S_CDC_LINE_CODING, *AT91PS_CDC_LINE_CODING;
258
259 AT91S_CDC_LINE_CODING line = {
260 115200, // baudrate
261 0, // 1 Stop Bit
262 0, // None Parity
263 8}; // 8 Data bits
264
265 void AT91F_CDC_Enumerate();
266
267 AT91PS_UDP pUdp = AT91C_BASE_UDP;
268 byte_t btConfiguration = 0;
269 byte_t btConnection = 0;
270 byte_t btReceiveBank = AT91C_UDP_RX_DATA_BK0;
271
272 //*----------------------------------------------------------------------------
273 //* \fn usb_disable
274 //* \brief This function deactivates the USB device
275 //*----------------------------------------------------------------------------
276 void usb_disable() {
277 // Disconnect the USB device
278 AT91C_BASE_PIOA->PIO_ODR = GPIO_USB_PU;
279
280 // Clear all lingering interrupts
281 if(pUdp->UDP_ISR & AT91C_UDP_ENDBUSRES) {
282 pUdp->UDP_ICR = AT91C_UDP_ENDBUSRES;
283 }
284 }
285
286 //*----------------------------------------------------------------------------
287 //* \fn usb_enable
288 //* \brief This function Activates the USB device
289 //*----------------------------------------------------------------------------
290 void usb_enable() {
291 // Set the PLL USB Divider
292 AT91C_BASE_CKGR->CKGR_PLLR |= AT91C_CKGR_USBDIV_1 ;
293
294 // Specific Chip USB Initialisation
295 // Enables the 48MHz USB clock UDPCK and System Peripheral USB Clock
296 AT91C_BASE_PMC->PMC_SCER = AT91C_PMC_UDP;
297 AT91C_BASE_PMC->PMC_PCER = (1 << AT91C_ID_UDP);
298
299 // Enable UDP PullUp (USB_DP_PUP) : enable & Clear of the corresponding PIO
300 // Set in PIO mode and Configure in Output
301 AT91C_BASE_PIOA->PIO_PER = GPIO_USB_PU; // Set in PIO mode
302 AT91C_BASE_PIOA->PIO_OER = GPIO_USB_PU; // Configure as Output
303
304 // Clear for set the Pullup resistor
305 AT91C_BASE_PIOA->PIO_CODR = GPIO_USB_PU;
306
307 // Disconnect and reconnect USB controller for 100ms
308 usb_disable();
309
310 // Wait for a short while
311 for (volatile size_t i=0; i<0x100000; i++);
312
313 // Reconnect USB reconnect
314 AT91C_BASE_PIOA->PIO_SODR = GPIO_USB_PU;
315 AT91C_BASE_PIOA->PIO_OER = GPIO_USB_PU;
316 }
317
318 //*----------------------------------------------------------------------------
319 //* \fn usb_check
320 //* \brief Test if the device is configured and handle enumeration
321 //*----------------------------------------------------------------------------
322 bool usb_check() {
323 AT91_REG isr = pUdp->UDP_ISR;
324
325 if (isr & AT91C_UDP_ENDBUSRES) {
326 pUdp->UDP_ICR = AT91C_UDP_ENDBUSRES;
327 // reset all endpoints
328 pUdp->UDP_RSTEP = (unsigned int)-1;
329 pUdp->UDP_RSTEP = 0;
330 // Enable the function
331 pUdp->UDP_FADDR = AT91C_UDP_FEN;
332 // Configure endpoint 0
333 pUdp->UDP_CSR[AT91C_EP_CONTROL] = (AT91C_UDP_EPEDS | AT91C_UDP_EPTYPE_CTRL);
334 }
335 else if (isr & AT91C_UDP_EPINT0) {
336 pUdp->UDP_ICR = AT91C_UDP_EPINT0;
337 AT91F_CDC_Enumerate();
338 }
339 return (btConfiguration) ? true : false;
340 }
341
342
343 bool usb_poll()
344 {
345 if (!usb_check()) return false;
346 return (pUdp->UDP_CSR[AT91C_EP_OUT] & btReceiveBank);
347 }
348
349 /**
350 In github PR #129, some users appears to get a false positive from
351 usb_poll, which returns true, but the usb_read operation
352 still returns 0.
353 This check is basically the same as above, but also checks
354 that the length available to read is non-zero, thus hopefully fixes the
355 bug.
356 **/
357 bool usb_poll_validate_length()
358 {
359
360 if (!usb_check()) return false;
361 if (!(pUdp->UDP_CSR[AT91C_EP_OUT] & btReceiveBank)) return false;
362 return (pUdp->UDP_CSR[AT91C_EP_OUT] >> 16) > 0;
363 }
364
365 //*----------------------------------------------------------------------------
366 //* \fn usb_read
367 //* \brief Read available data from Endpoint OUT
368 //*----------------------------------------------------------------------------
369 uint32_t usb_read(byte_t* data, size_t len) {
370 byte_t bank = btReceiveBank;
371 uint32_t packetSize, nbBytesRcv = 0;
372 uint32_t time_out = 0;
373
374 while (len) {
375 if (!usb_check()) break;
376
377 if ( pUdp->UDP_CSR[AT91C_EP_OUT] & bank ) {
378 packetSize = MIN(pUdp->UDP_CSR[AT91C_EP_OUT] >> 16, len);
379 len -= packetSize;
380 while(packetSize--)
381 data[nbBytesRcv++] = pUdp->UDP_FDR[AT91C_EP_OUT];
382 UDP_CLEAR_EP_FLAGS(AT91C_EP_OUT, bank);
383 if (bank == AT91C_UDP_RX_DATA_BK0) {
384 bank = AT91C_UDP_RX_DATA_BK1;
385 } else {
386 bank = AT91C_UDP_RX_DATA_BK0;
387 }
388 }
389 if (time_out++ == 0x1fff) break;
390 }
391
392 btReceiveBank = bank;
393 return nbBytesRcv;
394 }
395
396 //*----------------------------------------------------------------------------
397 //* \fn usb_write
398 //* \brief Send through endpoint 2
399 //*----------------------------------------------------------------------------
400 uint32_t usb_write(const byte_t* data, const size_t len) {
401 size_t length = len;
402 uint32_t cpt = 0;
403
404 if (!length) return 0;
405 if (!usb_check()) return 0;
406
407 // Send the first packet
408 cpt = MIN(length, AT91C_EP_IN_SIZE-1);
409 length -= cpt;
410 while (cpt--) pUdp->UDP_FDR[AT91C_EP_IN] = *data++;
411 UDP_SET_EP_FLAGS(AT91C_EP_IN, AT91C_UDP_TXPKTRDY);
412
413 while (length) {
414 // Fill the second bank
415 cpt = MIN(length, AT91C_EP_IN_SIZE-1);
416 length -= cpt;
417 while (cpt--) pUdp->UDP_FDR[AT91C_EP_IN] = *data++;
418 // Wait for the first bank to be sent
419 while (!(pUdp->UDP_CSR[AT91C_EP_IN] & AT91C_UDP_TXCOMP)) {
420 if (!usb_check()) return length;
421 }
422 UDP_CLEAR_EP_FLAGS(AT91C_EP_IN, AT91C_UDP_TXCOMP);
423 while (pUdp->UDP_CSR[AT91C_EP_IN] & AT91C_UDP_TXCOMP);
424 UDP_SET_EP_FLAGS(AT91C_EP_IN, AT91C_UDP_TXPKTRDY);
425 }
426
427 // Wait for the end of transfer
428 while (!(pUdp->UDP_CSR[AT91C_EP_IN] & AT91C_UDP_TXCOMP)) {
429 if (!usb_check()) return length;
430 }
431
432 UDP_CLEAR_EP_FLAGS(AT91C_EP_IN, AT91C_UDP_TXCOMP);
433 while (pUdp->UDP_CSR[AT91C_EP_IN] & AT91C_UDP_TXCOMP);
434
435 return length;
436 }
437
438 //*----------------------------------------------------------------------------
439 //* \fn AT91F_USB_SendData
440 //* \brief Send Data through the control endpoint
441 //*----------------------------------------------------------------------------
442 unsigned int csrTab[100] = {0x00};
443 unsigned char csrIdx = 0;
444
445 static void AT91F_USB_SendData(AT91PS_UDP pUdp, const char *pData, uint32_t length) {
446 uint32_t cpt = 0;
447 AT91_REG csr;
448
449 do {
450 cpt = MIN(length, 8);
451 length -= cpt;
452
453 while (cpt--)
454 pUdp->UDP_FDR[0] = *pData++;
455
456 if (pUdp->UDP_CSR[AT91C_EP_CONTROL] & AT91C_UDP_TXCOMP) {
457 UDP_CLEAR_EP_FLAGS(AT91C_EP_CONTROL, AT91C_UDP_TXCOMP);
458 while (pUdp->UDP_CSR[AT91C_EP_CONTROL] & AT91C_UDP_TXCOMP);
459 }
460
461 UDP_SET_EP_FLAGS(AT91C_EP_CONTROL, AT91C_UDP_TXPKTRDY);
462 do {
463 csr = pUdp->UDP_CSR[AT91C_EP_CONTROL];
464
465 // Data IN stage has been stopped by a status OUT
466 if (csr & AT91C_UDP_RX_DATA_BK0) {
467 UDP_CLEAR_EP_FLAGS(AT91C_EP_CONTROL, AT91C_UDP_RX_DATA_BK0);
468 return;
469 }
470 } while ( !(csr & AT91C_UDP_TXCOMP) );
471
472 } while (length);
473
474 if (pUdp->UDP_CSR[AT91C_EP_CONTROL] & AT91C_UDP_TXCOMP) {
475 UDP_CLEAR_EP_FLAGS(AT91C_EP_CONTROL, AT91C_UDP_TXCOMP);
476 while (pUdp->UDP_CSR[AT91C_EP_CONTROL] & AT91C_UDP_TXCOMP);
477 }
478 }
479
480 //*----------------------------------------------------------------------------
481 //* \fn AT91F_USB_SendZlp
482 //* \brief Send zero length packet through the control endpoint
483 //*----------------------------------------------------------------------------
484 void AT91F_USB_SendZlp(AT91PS_UDP pUdp) {
485 UDP_SET_EP_FLAGS(AT91C_EP_CONTROL, AT91C_UDP_TXPKTRDY);
486 while ( !(pUdp->UDP_CSR[AT91C_EP_CONTROL] & AT91C_UDP_TXCOMP) );
487 UDP_CLEAR_EP_FLAGS(AT91C_EP_CONTROL, AT91C_UDP_TXCOMP);
488 while (pUdp->UDP_CSR[AT91C_EP_CONTROL] & AT91C_UDP_TXCOMP);
489 }
490
491 //*----------------------------------------------------------------------------
492 //* \fn AT91F_USB_SendStall
493 //* \brief Stall the control endpoint
494 //*----------------------------------------------------------------------------
495 void AT91F_USB_SendStall(AT91PS_UDP pUdp) {
496 UDP_SET_EP_FLAGS(AT91C_EP_CONTROL, AT91C_UDP_FORCESTALL);
497 while ( !(pUdp->UDP_CSR[AT91C_EP_CONTROL] & AT91C_UDP_ISOERROR) );
498 UDP_CLEAR_EP_FLAGS(AT91C_EP_CONTROL, AT91C_UDP_FORCESTALL | AT91C_UDP_ISOERROR);
499 while (pUdp->UDP_CSR[AT91C_EP_CONTROL] & (AT91C_UDP_FORCESTALL | AT91C_UDP_ISOERROR));
500 }
501
502 //*----------------------------------------------------------------------------
503 //* \fn AT91F_CDC_Enumerate
504 //* \brief This function is a callback invoked when a SETUP packet is received
505 //*----------------------------------------------------------------------------
506 void AT91F_CDC_Enumerate() {
507 byte_t bmRequestType, bRequest;
508 uint16_t wValue, wIndex, wLength, wStatus;
509
510 if ( !(pUdp->UDP_CSR[AT91C_EP_CONTROL] & AT91C_UDP_RXSETUP) )
511 return;
512
513 bmRequestType = pUdp->UDP_FDR[0];
514 bRequest = pUdp->UDP_FDR[0];
515 wValue = (pUdp->UDP_FDR[0] & 0xFF);
516 wValue |= (pUdp->UDP_FDR[0] << 8);
517 wIndex = (pUdp->UDP_FDR[0] & 0xFF);
518 wIndex |= (pUdp->UDP_FDR[0] << 8);
519 wLength = (pUdp->UDP_FDR[0] & 0xFF);
520 wLength |= (pUdp->UDP_FDR[0] << 8);
521
522 if (bmRequestType & 0x80) {
523 UDP_SET_EP_FLAGS(AT91C_EP_CONTROL, AT91C_UDP_DIR);
524 while ( !(pUdp->UDP_CSR[AT91C_EP_CONTROL] & AT91C_UDP_DIR) );
525 }
526 UDP_CLEAR_EP_FLAGS(AT91C_EP_CONTROL, AT91C_UDP_RXSETUP);
527 while ( (pUdp->UDP_CSR[AT91C_EP_CONTROL] & AT91C_UDP_RXSETUP) );
528
529 // Handle supported standard device request Cf Table 9-3 in USB specification Rev 1.1
530 switch ((bRequest << 8) | bmRequestType) {
531 case STD_GET_DESCRIPTOR:
532 if (wValue == 0x100) // Return Device Descriptor
533 AT91F_USB_SendData(pUdp, devDescriptor, MIN(sizeof(devDescriptor), wLength));
534 else if (wValue == 0x200) // Return Configuration Descriptor
535 AT91F_USB_SendData(pUdp, cfgDescriptor, MIN(sizeof(cfgDescriptor), wLength));
536 else if ((wValue & 0xF00) == 0x300) { // Return String Descriptor
537 const char *strDescriptor = getStringDescriptor(wValue & 0xff);
538 if (strDescriptor != NULL) {
539 AT91F_USB_SendData(pUdp, strDescriptor, MIN(strDescriptor[0], wLength));
540 } else {
541 AT91F_USB_SendStall(pUdp);
542 }
543 }
544 else
545 AT91F_USB_SendStall(pUdp);
546 break;
547 case STD_SET_ADDRESS:
548 AT91F_USB_SendZlp(pUdp);
549 pUdp->UDP_FADDR = (AT91C_UDP_FEN | wValue);
550 pUdp->UDP_GLBSTATE = (wValue) ? AT91C_UDP_FADDEN : 0;
551 break;
552 case STD_SET_CONFIGURATION:
553 btConfiguration = wValue;
554 AT91F_USB_SendZlp(pUdp);
555 pUdp->UDP_GLBSTATE = (wValue) ? AT91C_UDP_CONFG : AT91C_UDP_FADDEN;
556 pUdp->UDP_CSR[1] = (wValue) ? (AT91C_UDP_EPEDS | AT91C_UDP_EPTYPE_BULK_OUT) : 0;
557 pUdp->UDP_CSR[2] = (wValue) ? (AT91C_UDP_EPEDS | AT91C_UDP_EPTYPE_BULK_IN) : 0;
558 pUdp->UDP_CSR[3] = (wValue) ? (AT91C_UDP_EPEDS | AT91C_UDP_EPTYPE_INT_IN) : 0;
559 break;
560 case STD_GET_CONFIGURATION:
561 AT91F_USB_SendData(pUdp, (char *) &(btConfiguration), sizeof(btConfiguration));
562 break;
563 case STD_GET_STATUS_ZERO:
564 wStatus = 0;
565 AT91F_USB_SendData(pUdp, (char *) &wStatus, sizeof(wStatus));
566 break;
567 case STD_GET_STATUS_INTERFACE:
568 wStatus = 0;
569 AT91F_USB_SendData(pUdp, (char *) &wStatus, sizeof(wStatus));
570 break;
571 case STD_GET_STATUS_ENDPOINT:
572 wStatus = 0;
573 wIndex &= 0x0F;
574 if ((pUdp->UDP_GLBSTATE & AT91C_UDP_CONFG) && (wIndex <= 3)) {
575 wStatus = (pUdp->UDP_CSR[wIndex] & AT91C_UDP_EPEDS) ? 0 : 1;
576 AT91F_USB_SendData(pUdp, (char *) &wStatus, sizeof(wStatus));
577 }
578 else if ((pUdp->UDP_GLBSTATE & AT91C_UDP_FADDEN) && (wIndex == 0)) {
579 wStatus = (pUdp->UDP_CSR[wIndex] & AT91C_UDP_EPEDS) ? 0 : 1;
580 AT91F_USB_SendData(pUdp, (char *) &wStatus, sizeof(wStatus));
581 }
582 else
583 AT91F_USB_SendStall(pUdp);
584 break;
585 case STD_SET_FEATURE_ZERO:
586 AT91F_USB_SendStall(pUdp);
587 break;
588 case STD_SET_FEATURE_INTERFACE:
589 AT91F_USB_SendZlp(pUdp);
590 break;
591 case STD_SET_FEATURE_ENDPOINT:
592 wIndex &= 0x0F;
593 if ((wValue == 0) && wIndex && (wIndex <= 3)) {
594 pUdp->UDP_CSR[wIndex] = 0;
595 AT91F_USB_SendZlp(pUdp);
596 }
597 else
598 AT91F_USB_SendStall(pUdp);
599 break;
600 case STD_CLEAR_FEATURE_ZERO:
601 AT91F_USB_SendStall(pUdp);
602 break;
603 case STD_CLEAR_FEATURE_INTERFACE:
604 AT91F_USB_SendZlp(pUdp);
605 break;
606 case STD_CLEAR_FEATURE_ENDPOINT:
607 wIndex &= 0x0F;
608 if ((wValue == 0) && wIndex && (wIndex <= 3)) {
609 if (wIndex == 1)
610 pUdp->UDP_CSR[1] = (AT91C_UDP_EPEDS | AT91C_UDP_EPTYPE_BULK_OUT);
611 else if (wIndex == 2)
612 pUdp->UDP_CSR[2] = (AT91C_UDP_EPEDS | AT91C_UDP_EPTYPE_BULK_IN);
613 else if (wIndex == 3)
614 pUdp->UDP_CSR[3] = (AT91C_UDP_EPEDS | AT91C_UDP_EPTYPE_ISO_IN);
615 AT91F_USB_SendZlp(pUdp);
616 }
617 else
618 AT91F_USB_SendStall(pUdp);
619 break;
620
621 // handle CDC class requests
622 case SET_LINE_CODING:
623 while ( !(pUdp->UDP_CSR[AT91C_EP_CONTROL] & AT91C_UDP_RX_DATA_BK0) );
624 UDP_CLEAR_EP_FLAGS(AT91C_EP_CONTROL, AT91C_UDP_RX_DATA_BK0);
625 AT91F_USB_SendZlp(pUdp);
626 break;
627 case GET_LINE_CODING:
628 AT91F_USB_SendData(pUdp, (char *) &line, MIN(sizeof(line), wLength));
629 break;
630 case SET_CONTROL_LINE_STATE:
631 btConnection = wValue;
632 AT91F_USB_SendZlp(pUdp);
633 break;
634 default:
635 AT91F_USB_SendStall(pUdp);
636 break;
637 }
638 }
Impressum, Datenschutz