]> git.zerfleddert.de Git - proxmark3-svn/blob - common/usb_cdc.c
CHG: change the number of calls to prng_successor was done. Fewer should mean faster :)
[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 "config_gpio.h"
37
38 #define MIN(a, b) (((a) < (b)) ? (a) : (b))
39 #define MAX(a, b) (((a) > (b)) ? (a) : (b))
40 #define AT91C_EP_IN_SIZE 0x40
41 #define AT91C_EP_OUT 1
42 #define AT91C_EP_OUT_SIZE 0x40
43 #define AT91C_EP_IN 2
44
45 const char devDescriptor[] = {
46 /* Device descriptor */
47 0x12, // bLength
48 0x01, // bDescriptorType
49 //0x10,0x01, // Complies with USB Spec. Release (0110h = release 1.10)
50 0x00,0x02, // Complies with USB Spec. Release (0110h = release 2.00)
51 0x02, // bDeviceClass: CDC class code
52 0x00, // bDeviceSubclass: CDC class sub code
53 0x00, // bDeviceProtocol: CDC Device protocol
54 0x08, // bMaxPacketSize0
55 0x2d,0x2d, // Vendor ID (--)
56 0x4d,0x50, // Product ID (PM), transmitted in reverse
57 0x01,0x00, // Device release number (0001)
58 0x01, // iManufacturer // 0x01
59 0x00, // iProduct
60 0x00, // SerialNumber
61 0x01 // bNumConfigs
62 };
63
64 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 0x00, // 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 0x00, // 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 0x00, // 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 const char strDescriptor[] = {
156 26, // Length
157 0x03, // Type is string
158 'p', 0x00,
159 'r', 0x00,
160 'o', 0x00,
161 'x', 0x00,
162 'm', 0x00,
163 'a', 0x00,
164 'r', 0x00,
165 'k', 0x00,
166 '.', 0x00,
167 'o', 0x00,
168 'r', 0x00,
169 'g', 0x00,
170 };
171
172
173 /* USB standard request code */
174 #define STD_GET_STATUS_ZERO 0x0080
175 #define STD_GET_STATUS_INTERFACE 0x0081
176 #define STD_GET_STATUS_ENDPOINT 0x0082
177
178 #define STD_CLEAR_FEATURE_ZERO 0x0100
179 #define STD_CLEAR_FEATURE_INTERFACE 0x0101
180 #define STD_CLEAR_FEATURE_ENDPOINT 0x0102
181
182 #define STD_SET_FEATURE_ZERO 0x0300
183 #define STD_SET_FEATURE_INTERFACE 0x0301
184 #define STD_SET_FEATURE_ENDPOINT 0x0302
185
186 #define STD_SET_ADDRESS 0x0500
187 #define STD_GET_DESCRIPTOR 0x0680
188 #define STD_SET_DESCRIPTOR 0x0700
189 #define STD_GET_CONFIGURATION 0x0880
190 #define STD_SET_CONFIGURATION 0x0900
191 #define STD_GET_INTERFACE 0x0A81
192 #define STD_SET_INTERFACE 0x0B01
193 #define STD_SYNCH_FRAME 0x0C82
194
195 /* CDC Class Specific Request Code */
196 #define GET_LINE_CODING 0x21A1
197 #define SET_LINE_CODING 0x2021
198 #define SET_CONTROL_LINE_STATE 0x2221
199
200 typedef struct {
201 unsigned int dwDTERRate;
202 char bCharFormat;
203 char bParityType;
204 char bDataBits;
205 } AT91S_CDC_LINE_CODING, *AT91PS_CDC_LINE_CODING;
206
207 AT91S_CDC_LINE_CODING line = {
208 115200, // baudrate
209 0, // 1 Stop Bit
210 0, // None Parity
211 8}; // 8 Data bits
212
213 void AT91F_CDC_Enumerate();
214
215 AT91PS_UDP pUdp = AT91C_BASE_UDP;
216 byte_t btConfiguration = 0;
217 byte_t btConnection = 0;
218 byte_t btReceiveBank = AT91C_UDP_RX_DATA_BK0;
219
220 //*----------------------------------------------------------------------------
221 //* \fn usb_disable
222 //* \brief This function deactivates the USB device
223 //*----------------------------------------------------------------------------
224 void usb_disable() {
225 // Disconnect the USB device
226 AT91C_BASE_PIOA->PIO_ODR = GPIO_USB_PU;
227
228 // Clear all lingering interrupts
229 if(pUdp->UDP_ISR & AT91C_UDP_ENDBUSRES) {
230 pUdp->UDP_ICR = AT91C_UDP_ENDBUSRES;
231 }
232 }
233
234 //*----------------------------------------------------------------------------
235 //* \fn usb_enable
236 //* \brief This function Activates the USB device
237 //*----------------------------------------------------------------------------
238 void usb_enable() {
239 // Set the PLL USB Divider
240 AT91C_BASE_CKGR->CKGR_PLLR |= AT91C_CKGR_USBDIV_1 ;
241
242 // Specific Chip USB Initialisation
243 // Enables the 48MHz USB clock UDPCK and System Peripheral USB Clock
244 AT91C_BASE_PMC->PMC_SCER = AT91C_PMC_UDP;
245 AT91C_BASE_PMC->PMC_PCER = (1 << AT91C_ID_UDP);
246
247 // Enable UDP PullUp (USB_DP_PUP) : enable & Clear of the corresponding PIO
248 // Set in PIO mode and Configure in Output
249 AT91C_BASE_PIOA->PIO_PER = GPIO_USB_PU; // Set in PIO mode
250 AT91C_BASE_PIOA->PIO_OER = GPIO_USB_PU; // Configure as Output
251
252 // Clear for set the Pullup resistor
253 AT91C_BASE_PIOA->PIO_CODR = GPIO_USB_PU;
254
255 // Disconnect and reconnect USB controller for 100ms
256 usb_disable();
257
258 // Wait for a short while
259 for (volatile size_t i=0; i<0x100000; i++);
260 //sleep(1);
261
262 // Reconnect USB reconnect
263 AT91C_BASE_PIOA->PIO_SODR = GPIO_USB_PU;
264 AT91C_BASE_PIOA->PIO_OER = GPIO_USB_PU;
265 }
266
267 //*----------------------------------------------------------------------------
268 //* \fn usb_check
269 //* \brief Test if the device is configured and handle enumeration
270 //*----------------------------------------------------------------------------
271 bool usb_check() {
272 AT91_REG isr = pUdp->UDP_ISR;
273
274 if (isr & AT91C_UDP_ENDBUSRES) {
275 pUdp->UDP_ICR = AT91C_UDP_ENDBUSRES;
276 // reset all endpoints
277 pUdp->UDP_RSTEP = (unsigned int)-1;
278 pUdp->UDP_RSTEP = 0;
279 // Enable the function
280 pUdp->UDP_FADDR = AT91C_UDP_FEN;
281 // Configure endpoint 0
282 pUdp->UDP_CSR[0] = (AT91C_UDP_EPEDS | AT91C_UDP_EPTYPE_CTRL);
283 }
284 else if (isr & AT91C_UDP_EPINT0) {
285 pUdp->UDP_ICR = AT91C_UDP_EPINT0;
286 AT91F_CDC_Enumerate();
287 }
288 return (btConfiguration) ? true : false;
289 }
290
291
292 bool usb_poll()
293 {
294 if (!usb_check()) return false;
295 return (pUdp->UDP_CSR[AT91C_EP_OUT] & btReceiveBank);
296 }
297
298 /**
299 In github PR #129, some users appears to get a false positive from
300 usb_poll, which returns true, but the usb_read operation
301 still returns 0.
302 This check is basically the same as above, but also checks
303 that the length available to read is non-zero, thus hopefully fixes the
304 bug.
305 **/
306 bool usb_poll_validate_length()
307 {
308 if (!usb_check()) return false;
309 if (!(pUdp->UDP_CSR[AT91C_EP_OUT] & btReceiveBank)) return false;
310 return (pUdp->UDP_CSR[AT91C_EP_OUT] >> 16) > 0;
311 }
312
313 //*----------------------------------------------------------------------------
314 //* \fn usb_read
315 //* \brief Read available data from Endpoint OUT
316 //*----------------------------------------------------------------------------
317 uint32_t usb_read(byte_t* data, size_t len) {
318 byte_t bank = btReceiveBank;
319 uint32_t packetSize, nbBytesRcv = 0;
320 uint32_t time_out = 0;
321
322 while (len) {
323 if (!usb_check()) break;
324
325 if ( pUdp->UDP_CSR[AT91C_EP_OUT] & bank ) {
326 packetSize = MIN(pUdp->UDP_CSR[AT91C_EP_OUT] >> 16, len);
327 len -= packetSize;
328 while(packetSize--)
329 data[nbBytesRcv++] = pUdp->UDP_FDR[AT91C_EP_OUT];
330
331 pUdp->UDP_CSR[AT91C_EP_OUT] &= ~(bank);
332
333 if (bank == AT91C_UDP_RX_DATA_BK0)
334 bank = AT91C_UDP_RX_DATA_BK1;
335 else
336 bank = AT91C_UDP_RX_DATA_BK0;
337 }
338 if (time_out++ == 0x1fff) break;
339 }
340
341 btReceiveBank = bank;
342 return nbBytesRcv;
343 }
344
345 //*----------------------------------------------------------------------------
346 //* \fn usb_write
347 //* \brief Send through endpoint 2
348 //*----------------------------------------------------------------------------
349 uint32_t usb_write(const byte_t* data, const size_t len) {
350 size_t length = len;
351 uint32_t cpt = 0;
352
353 if (!length) return 0;
354 if (!usb_check()) return 0;
355
356 // Send the first packet
357 cpt = MIN(length, AT91C_EP_IN_SIZE-1);
358 length -= cpt;
359 while (cpt--) pUdp->UDP_FDR[AT91C_EP_IN] = *data++;
360 pUdp->UDP_CSR[AT91C_EP_IN] |= AT91C_UDP_TXPKTRDY;
361
362 while (length) {
363 // Fill the second bank
364 cpt = MIN(length, AT91C_EP_IN_SIZE-1);
365 length -= cpt;
366 while (cpt--) pUdp->UDP_FDR[AT91C_EP_IN] = *data++;
367 // Wait for the first bank to be sent
368 while (!(pUdp->UDP_CSR[AT91C_EP_IN] & AT91C_UDP_TXCOMP)) {
369 if (!usb_check()) return length;
370 }
371 pUdp->UDP_CSR[AT91C_EP_IN] &= ~(AT91C_UDP_TXCOMP);
372
373 while (pUdp->UDP_CSR[AT91C_EP_IN] & AT91C_UDP_TXCOMP);
374
375 pUdp->UDP_CSR[AT91C_EP_IN] |= AT91C_UDP_TXPKTRDY;
376 }
377
378 // Wait for the end of transfer
379 while (!(pUdp->UDP_CSR[AT91C_EP_IN] & AT91C_UDP_TXCOMP)) {
380 if (!usb_check()) return length;
381 }
382
383 pUdp->UDP_CSR[AT91C_EP_IN] &= ~(AT91C_UDP_TXCOMP);
384 while (pUdp->UDP_CSR[AT91C_EP_IN] & AT91C_UDP_TXCOMP);
385
386 return length;
387 }
388
389 //*----------------------------------------------------------------------------
390 //* \fn AT91F_USB_SendData
391 //* \brief Send Data through the control endpoint
392 //*----------------------------------------------------------------------------
393 unsigned int csrTab[100] = {0x00};
394 unsigned char csrIdx = 0;
395
396 static void AT91F_USB_SendData(AT91PS_UDP pUdp, const char *pData, uint32_t length) {
397 uint32_t cpt = 0;
398 AT91_REG csr;
399
400 do {
401 cpt = MIN(length, 8);
402 length -= cpt;
403
404 while (cpt--)
405 pUdp->UDP_FDR[0] = *pData++;
406
407 if (pUdp->UDP_CSR[0] & AT91C_UDP_TXCOMP) {
408 pUdp->UDP_CSR[0] &= ~(AT91C_UDP_TXCOMP);
409 while (pUdp->UDP_CSR[0] & AT91C_UDP_TXCOMP);
410 }
411
412 pUdp->UDP_CSR[0] |= AT91C_UDP_TXPKTRDY;
413 do {
414 csr = pUdp->UDP_CSR[0];
415
416 // Data IN stage has been stopped by a status OUT
417 if (csr & AT91C_UDP_RX_DATA_BK0) {
418 pUdp->UDP_CSR[0] &= ~(AT91C_UDP_RX_DATA_BK0);
419 return;
420 }
421 } while ( !(csr & AT91C_UDP_TXCOMP) );
422
423 } while (length);
424
425 if (pUdp->UDP_CSR[0] & AT91C_UDP_TXCOMP) {
426 pUdp->UDP_CSR[0] &= ~(AT91C_UDP_TXCOMP);
427 while (pUdp->UDP_CSR[0] & AT91C_UDP_TXCOMP);
428 }
429 }
430
431 //*----------------------------------------------------------------------------
432 //* \fn AT91F_USB_SendZlp
433 //* \brief Send zero length packet through the control endpoint
434 //*----------------------------------------------------------------------------
435 void AT91F_USB_SendZlp(AT91PS_UDP pUdp) {
436 pUdp->UDP_CSR[0] |= AT91C_UDP_TXPKTRDY;
437 while ( !(pUdp->UDP_CSR[0] & AT91C_UDP_TXCOMP) );
438 pUdp->UDP_CSR[0] &= ~(AT91C_UDP_TXCOMP);
439 while (pUdp->UDP_CSR[0] & AT91C_UDP_TXCOMP);
440 }
441
442 //*----------------------------------------------------------------------------
443 //* \fn AT91F_USB_SendStall
444 //* \brief Stall the control endpoint
445 //*----------------------------------------------------------------------------
446 void AT91F_USB_SendStall(AT91PS_UDP pUdp) {
447 pUdp->UDP_CSR[0] |= AT91C_UDP_FORCESTALL;
448 while ( !(pUdp->UDP_CSR[0] & AT91C_UDP_ISOERROR) );
449 pUdp->UDP_CSR[0] &= ~(AT91C_UDP_FORCESTALL | AT91C_UDP_ISOERROR);
450 while (pUdp->UDP_CSR[0] & (AT91C_UDP_FORCESTALL | AT91C_UDP_ISOERROR));
451 }
452
453 //*----------------------------------------------------------------------------
454 //* \fn AT91F_CDC_Enumerate
455 //* \brief This function is a callback invoked when a SETUP packet is received
456 //*----------------------------------------------------------------------------
457 void AT91F_CDC_Enumerate() {
458 byte_t bmRequestType, bRequest;
459 uint16_t wValue, wIndex, wLength, wStatus;
460
461 if ( !(pUdp->UDP_CSR[0] & AT91C_UDP_RXSETUP) )
462 return;
463
464 bmRequestType = pUdp->UDP_FDR[0];
465 bRequest = pUdp->UDP_FDR[0];
466 wValue = (pUdp->UDP_FDR[0] & 0xFF);
467 wValue |= (pUdp->UDP_FDR[0] << 8);
468 wIndex = (pUdp->UDP_FDR[0] & 0xFF);
469 wIndex |= (pUdp->UDP_FDR[0] << 8);
470 wLength = (pUdp->UDP_FDR[0] & 0xFF);
471 wLength |= (pUdp->UDP_FDR[0] << 8);
472
473 if (bmRequestType & 0x80) {
474 pUdp->UDP_CSR[0] |= AT91C_UDP_DIR;
475 while ( !(pUdp->UDP_CSR[0] & AT91C_UDP_DIR) );
476 }
477 pUdp->UDP_CSR[0] &= ~AT91C_UDP_RXSETUP;
478 while ( (pUdp->UDP_CSR[0] & AT91C_UDP_RXSETUP) );
479
480 // Handle supported standard device request Cf Table 9-3 in USB specification Rev 1.1
481 switch ((bRequest << 8) | bmRequestType) {
482 case STD_GET_DESCRIPTOR:
483 if (wValue == 0x100) // Return Device Descriptor
484 AT91F_USB_SendData(pUdp, devDescriptor, MIN(sizeof(devDescriptor), wLength));
485 else if (wValue == 0x200) // Return Configuration Descriptor
486 AT91F_USB_SendData(pUdp, cfgDescriptor, MIN(sizeof(cfgDescriptor), wLength));
487 else if ((wValue & 0x300) == 0x300) // Return String Descriptor
488 AT91F_USB_SendData(pUdp, strDescriptor, MIN(sizeof(strDescriptor), wLength));
489 else
490 AT91F_USB_SendStall(pUdp);
491 break;
492 case STD_SET_ADDRESS:
493 AT91F_USB_SendZlp(pUdp);
494 pUdp->UDP_FADDR = (AT91C_UDP_FEN | wValue);
495 pUdp->UDP_GLBSTATE = (wValue) ? AT91C_UDP_FADDEN : 0;
496 break;
497 case STD_SET_CONFIGURATION:
498 btConfiguration = wValue;
499 AT91F_USB_SendZlp(pUdp);
500 pUdp->UDP_GLBSTATE = (wValue) ? AT91C_UDP_CONFG : AT91C_UDP_FADDEN;
501 pUdp->UDP_CSR[1] = (wValue) ? (AT91C_UDP_EPEDS | AT91C_UDP_EPTYPE_BULK_OUT) : 0;
502 pUdp->UDP_CSR[2] = (wValue) ? (AT91C_UDP_EPEDS | AT91C_UDP_EPTYPE_BULK_IN) : 0;
503 pUdp->UDP_CSR[3] = (wValue) ? (AT91C_UDP_EPEDS | AT91C_UDP_EPTYPE_INT_IN) : 0;
504 break;
505 case STD_GET_CONFIGURATION:
506 AT91F_USB_SendData(pUdp, (char *) &(btConfiguration), sizeof(btConfiguration));
507 break;
508 case STD_GET_STATUS_ZERO:
509 wStatus = 0;
510 AT91F_USB_SendData(pUdp, (char *) &wStatus, sizeof(wStatus));
511 break;
512 case STD_GET_STATUS_INTERFACE:
513 wStatus = 0;
514 AT91F_USB_SendData(pUdp, (char *) &wStatus, sizeof(wStatus));
515 break;
516 case STD_GET_STATUS_ENDPOINT:
517 wStatus = 0;
518 wIndex &= 0x0F;
519 if ((pUdp->UDP_GLBSTATE & AT91C_UDP_CONFG) && (wIndex <= 3)) {
520 wStatus = (pUdp->UDP_CSR[wIndex] & AT91C_UDP_EPEDS) ? 0 : 1;
521 AT91F_USB_SendData(pUdp, (char *) &wStatus, sizeof(wStatus));
522 }
523 else if ((pUdp->UDP_GLBSTATE & AT91C_UDP_FADDEN) && (wIndex == 0)) {
524 wStatus = (pUdp->UDP_CSR[wIndex] & AT91C_UDP_EPEDS) ? 0 : 1;
525 AT91F_USB_SendData(pUdp, (char *) &wStatus, sizeof(wStatus));
526 }
527 else
528 AT91F_USB_SendStall(pUdp);
529 break;
530 case STD_SET_FEATURE_ZERO:
531 AT91F_USB_SendStall(pUdp);
532 break;
533 case STD_SET_FEATURE_INTERFACE:
534 AT91F_USB_SendZlp(pUdp);
535 break;
536 case STD_SET_FEATURE_ENDPOINT:
537 wIndex &= 0x0F;
538 if ((wValue == 0) && wIndex && (wIndex <= 3)) {
539 pUdp->UDP_CSR[wIndex] = 0;
540 AT91F_USB_SendZlp(pUdp);
541 }
542 else
543 AT91F_USB_SendStall(pUdp);
544 break;
545 case STD_CLEAR_FEATURE_ZERO:
546 AT91F_USB_SendStall(pUdp);
547 break;
548 case STD_CLEAR_FEATURE_INTERFACE:
549 AT91F_USB_SendZlp(pUdp);
550 break;
551 case STD_CLEAR_FEATURE_ENDPOINT:
552 wIndex &= 0x0F;
553 if ((wValue == 0) && wIndex && (wIndex <= 3)) {
554 if (wIndex == 1)
555 pUdp->UDP_CSR[1] = (AT91C_UDP_EPEDS | AT91C_UDP_EPTYPE_BULK_OUT);
556 else if (wIndex == 2)
557 pUdp->UDP_CSR[2] = (AT91C_UDP_EPEDS | AT91C_UDP_EPTYPE_BULK_IN);
558 else if (wIndex == 3)
559 pUdp->UDP_CSR[3] = (AT91C_UDP_EPEDS | AT91C_UDP_EPTYPE_ISO_IN);
560 AT91F_USB_SendZlp(pUdp);
561 }
562 else
563 AT91F_USB_SendStall(pUdp);
564 break;
565
566 // handle CDC class requests
567 case SET_LINE_CODING:
568 while ( !(pUdp->UDP_CSR[0] & AT91C_UDP_RX_DATA_BK0) );
569 pUdp->UDP_CSR[0] &= ~(AT91C_UDP_RX_DATA_BK0);
570 AT91F_USB_SendZlp(pUdp);
571 break;
572 case GET_LINE_CODING:
573 AT91F_USB_SendData(pUdp, (char *) &line, MIN(sizeof(line), wLength));
574 break;
575 case SET_CONTROL_LINE_STATE:
576 btConnection = wValue;
577 AT91F_USB_SendZlp(pUdp);
578 break;
579 default:
580 AT91F_USB_SendStall(pUdp);
581 break;
582 }
583 }
Impressum, Datenschutz