]> git.zerfleddert.de Git - proxmark3-svn/blob - armsrc/usb_cdc.c
added so-called 'driver' for windows
[proxmark3-svn] / armsrc / 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 "util.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 0x02, // bDeviceClass: CDC class code
51 0x00, // bDeviceSubclass: CDC class sub code
52 0x00, // bDeviceProtocol: CDC Device protocol
53 0x08, // bMaxPacketSize0
54 0x2d,0x2d, // Vendor ID (--)
55 0x4d,0x50, // Product ID (PM), transmitted in reverse
56 0x01,0x00, // Device release number (0001)
57 0x01, // iManufacturer // 0x01
58 0x00, // iProduct
59 0x00, // SerialNumber
60 0x01 // bNumConfigs
61 };
62
63 const char cfgDescriptor[] = {
64 /* ============== CONFIGURATION 1 =========== */
65 /* Configuration 1 descriptor */
66 0x09, // CbLength
67 0x02, // CbDescriptorType
68 0x43, // CwTotalLength 2 EP + Control
69 0x00,
70 0x02, // CbNumInterfaces
71 0x01, // CbConfigurationValue
72 0x00, // CiConfiguration
73 0xC0, // CbmAttributes 0xA0
74 0x00, // CMaxPower
75
76 /* Communication Class Interface Descriptor Requirement */
77 0x09, // bLength
78 0x04, // bDescriptorType
79 0x00, // bInterfaceNumber
80 0x00, // bAlternateSetting
81 0x01, // bNumEndpoints
82 0x02, // bInterfaceClass
83 0x02, // bInterfaceSubclass
84 0x00, // bInterfaceProtocol
85 0x00, // iInterface
86
87 /* Header Functional Descriptor */
88 0x05, // bFunction Length
89 0x24, // bDescriptor type: CS_INTERFACE
90 0x00, // bDescriptor subtype: Header Func Desc
91 0x10, // bcdCDC:1.1
92 0x01,
93
94 /* ACM Functional Descriptor */
95 0x04, // bFunctionLength
96 0x24, // bDescriptor Type: CS_INTERFACE
97 0x02, // bDescriptor Subtype: ACM Func Desc
98 0x00, // bmCapabilities
99
100 /* Union Functional Descriptor */
101 0x05, // bFunctionLength
102 0x24, // bDescriptorType: CS_INTERFACE
103 0x06, // bDescriptor Subtype: Union Func Desc
104 0x00, // bMasterInterface: Communication Class Interface
105 0x01, // bSlaveInterface0: Data Class Interface
106
107 /* Call Management Functional Descriptor */
108 0x05, // bFunctionLength
109 0x24, // bDescriptor Type: CS_INTERFACE
110 0x01, // bDescriptor Subtype: Call Management Func Desc
111 0x00, // bmCapabilities: D1 + D0
112 0x01, // bDataInterface: Data Class Interface 1
113
114 /* Endpoint 1 descriptor */
115 0x07, // bLength
116 0x05, // bDescriptorType
117 0x83, // bEndpointAddress, Endpoint 03 - IN
118 0x03, // bmAttributes INT
119 0x08, // wMaxPacketSize
120 0x00,
121 0xFF, // bInterval
122
123 /* Data Class Interface Descriptor Requirement */
124 0x09, // bLength
125 0x04, // bDescriptorType
126 0x01, // bInterfaceNumber
127 0x00, // bAlternateSetting
128 0x02, // bNumEndpoints
129 0x0A, // bInterfaceClass
130 0x00, // bInterfaceSubclass
131 0x00, // bInterfaceProtocol
132 0x00, // iInterface
133
134 /* First alternate setting */
135 /* Endpoint 1 descriptor */
136 0x07, // bLength
137 0x05, // bDescriptorType
138 0x01, // bEndpointAddress, Endpoint 01 - OUT
139 0x02, // bmAttributes BULK
140 AT91C_EP_OUT_SIZE, // wMaxPacketSize
141 0x00,
142 0x00, // bInterval
143
144 /* Endpoint 2 descriptor */
145 0x07, // bLength
146 0x05, // bDescriptorType
147 0x82, // bEndpointAddress, Endpoint 02 - IN
148 0x02, // bmAttributes BULK
149 AT91C_EP_IN_SIZE, // wMaxPacketSize
150 0x00,
151 0x00 // bInterval
152 };
153
154 const char strDescriptor[] = {
155 26, // Length
156 0x03, // Type is string
157 'p', 0x00,
158 'r', 0x00,
159 'o', 0x00,
160 'x', 0x00,
161 'm', 0x00,
162 'a', 0x00,
163 'r', 0x00,
164 'k', 0x00,
165 '.', 0x00,
166 'o', 0x00,
167 'r', 0x00,
168 'g', 0x00,
169 };
170
171
172 /* USB standard request code */
173 #define STD_GET_STATUS_ZERO 0x0080
174 #define STD_GET_STATUS_INTERFACE 0x0081
175 #define STD_GET_STATUS_ENDPOINT 0x0082
176
177 #define STD_CLEAR_FEATURE_ZERO 0x0100
178 #define STD_CLEAR_FEATURE_INTERFACE 0x0101
179 #define STD_CLEAR_FEATURE_ENDPOINT 0x0102
180
181 #define STD_SET_FEATURE_ZERO 0x0300
182 #define STD_SET_FEATURE_INTERFACE 0x0301
183 #define STD_SET_FEATURE_ENDPOINT 0x0302
184
185 #define STD_SET_ADDRESS 0x0500
186 #define STD_GET_DESCRIPTOR 0x0680
187 #define STD_SET_DESCRIPTOR 0x0700
188 #define STD_GET_CONFIGURATION 0x0880
189 #define STD_SET_CONFIGURATION 0x0900
190 #define STD_GET_INTERFACE 0x0A81
191 #define STD_SET_INTERFACE 0x0B01
192 #define STD_SYNCH_FRAME 0x0C82
193
194 /* CDC Class Specific Request Code */
195 #define GET_LINE_CODING 0x21A1
196 #define SET_LINE_CODING 0x2021
197 #define SET_CONTROL_LINE_STATE 0x2221
198
199 typedef struct {
200 unsigned int dwDTERRate;
201 char bCharFormat;
202 char bParityType;
203 char bDataBits;
204 } AT91S_CDC_LINE_CODING, *AT91PS_CDC_LINE_CODING;
205
206 AT91S_CDC_LINE_CODING line = {
207 115200, // baudrate
208 0, // 1 Stop Bit
209 0, // None Parity
210 8}; // 8 Data bits
211
212 void AT91F_CDC_Enumerate();
213
214 AT91PS_UDP pUdp = AT91C_BASE_UDP;
215 byte_t btConfiguration = 0;
216 byte_t btConnection = 0;
217 byte_t btReceiveBank = AT91C_UDP_RX_DATA_BK0;
218
219 //*----------------------------------------------------------------------------
220 //* \fn AT91F_USB_Disable
221 //* \brief This function deactivates the USB device
222 //*----------------------------------------------------------------------------
223 void usb_disable() {
224 // Disconnect and reconnect USB controller for 100ms
225 AT91C_BASE_PIOA->PIO_ODR = AT91C_PIO_PA24;
226 SpinDelay(100);
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 AT91F_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 = AT91C_PIO_PA16; // Set in PIO mode
250 AT91C_BASE_PIOA->PIO_OER = AT91C_PIO_PA16; // Configure as Output
251
252 // Clear for set the Pul up resistor
253 AT91C_BASE_PIOA->PIO_CODR = AT91C_PIO_PA16;
254
255 // Disconnect and USB device
256 usb_disable();
257
258 // Wait for a short while
259 SpinDelay(100);
260
261 // Reconnect USB reconnect
262 AT91C_BASE_PIOA->PIO_SODR = AT91C_PIO_PA24;
263 AT91C_BASE_PIOA->PIO_OER = AT91C_PIO_PA24;
264 }
265
266 //*----------------------------------------------------------------------------
267 //* \fn AT91F_UDP_IsConfigured
268 //* \brief Test if the device is configured and handle enumeration
269 //*----------------------------------------------------------------------------
270 bool usb_check() {
271 AT91_REG isr = pUdp->UDP_ISR;
272
273 if (isr & AT91C_UDP_ENDBUSRES) {
274 pUdp->UDP_ICR = AT91C_UDP_ENDBUSRES;
275 // reset all endpoints
276 pUdp->UDP_RSTEP = (unsigned int)-1;
277 pUdp->UDP_RSTEP = 0;
278 // Enable the function
279 pUdp->UDP_FADDR = AT91C_UDP_FEN;
280 // Configure endpoint 0
281 pUdp->UDP_CSR[0] = (AT91C_UDP_EPEDS | AT91C_UDP_EPTYPE_CTRL);
282 }
283 else if (isr & AT91C_UDP_EPINT0) {
284 pUdp->UDP_ICR = AT91C_UDP_EPINT0;
285 AT91F_CDC_Enumerate();
286 }
287 return (btConfiguration) ? true : false;
288 }
289
290
291 bool usb_poll()
292 {
293 if (!usb_check()) return false;
294 return (pUdp->UDP_CSR[AT91C_EP_OUT] & btReceiveBank);
295 }
296
297 //*----------------------------------------------------------------------------
298 //* \fn AT91F_UDP_Read
299 //* \brief Read available data from Endpoint OUT
300 //*----------------------------------------------------------------------------
301 uint32_t usb_read(byte_t* data, size_t len) {
302 byte_t bank = btReceiveBank;
303 uint32_t packetSize, nbBytesRcv = 0;
304 uint32_t time_out = 0;
305
306 while (len)
307 {
308 if (!usb_check()) break;
309
310 if ( pUdp->UDP_CSR[AT91C_EP_OUT] & bank ) {
311 packetSize = MIN(pUdp->UDP_CSR[AT91C_EP_OUT] >> 16, len);
312 len -= packetSize;
313 while(packetSize--)
314 data[nbBytesRcv++] = pUdp->UDP_FDR[AT91C_EP_OUT];
315 pUdp->UDP_CSR[AT91C_EP_OUT] &= ~(bank);
316 if (bank == AT91C_UDP_RX_DATA_BK0)
317 {
318 bank = AT91C_UDP_RX_DATA_BK1;
319 } else {
320 bank = AT91C_UDP_RX_DATA_BK0;
321 }
322 }
323 if (time_out++ == 0x1fff) break;
324 }
325
326 btReceiveBank = bank;
327 return nbBytesRcv;
328 }
329
330 //*----------------------------------------------------------------------------
331 //* \fn AT91F_CDC_Write
332 //* \brief Send through endpoint 2
333 //*----------------------------------------------------------------------------
334 uint32_t usb_write(const byte_t* data, const size_t len) {
335 size_t length = len;
336 uint32_t cpt = 0;
337
338 if (!length) return 0;
339 if (!usb_check()) return 0;
340
341 // Send the first packet
342 cpt = MIN(length, AT91C_EP_IN_SIZE-1);
343 length -= cpt;
344 while (cpt--) pUdp->UDP_FDR[AT91C_EP_IN] = *data++;
345 pUdp->UDP_CSR[AT91C_EP_IN] |= AT91C_UDP_TXPKTRDY;
346
347 while (length) {
348 // Fill the second bank
349 cpt = MIN(length, AT91C_EP_IN_SIZE-1);
350 length -= cpt;
351 while (cpt--) pUdp->UDP_FDR[AT91C_EP_IN] = *data++;
352 // Wait for the the first bank to be sent
353 while (!(pUdp->UDP_CSR[AT91C_EP_IN] & AT91C_UDP_TXCOMP)) {
354 if (!usb_check()) return length;
355 }
356 pUdp->UDP_CSR[AT91C_EP_IN] &= ~(AT91C_UDP_TXCOMP);
357 while (pUdp->UDP_CSR[AT91C_EP_IN] & AT91C_UDP_TXCOMP);
358 pUdp->UDP_CSR[AT91C_EP_IN] |= AT91C_UDP_TXPKTRDY;
359 }
360
361 // Wait for the end of transfer
362 while (!(pUdp->UDP_CSR[AT91C_EP_IN] & AT91C_UDP_TXCOMP)) {
363 if (!usb_check()) return length;
364 }
365
366 pUdp->UDP_CSR[AT91C_EP_IN] &= ~(AT91C_UDP_TXCOMP);
367 while (pUdp->UDP_CSR[AT91C_EP_IN] & AT91C_UDP_TXCOMP);
368
369 return length;
370 }
371
372 //*----------------------------------------------------------------------------
373 //* \fn AT91F_USB_SendData
374 //* \brief Send Data through the control endpoint
375 //*----------------------------------------------------------------------------
376 unsigned int csrTab[100];
377 unsigned char csrIdx = 0;
378
379 static void AT91F_USB_SendData(AT91PS_UDP pUdp, const char *pData, uint32_t length) {
380 uint32_t cpt = 0;
381 AT91_REG csr;
382
383 do {
384 cpt = MIN(length, 8);
385 length -= cpt;
386
387 while (cpt--)
388 pUdp->UDP_FDR[0] = *pData++;
389
390 if (pUdp->UDP_CSR[0] & AT91C_UDP_TXCOMP) {
391 pUdp->UDP_CSR[0] &= ~(AT91C_UDP_TXCOMP);
392 while (pUdp->UDP_CSR[0] & AT91C_UDP_TXCOMP);
393 }
394
395 pUdp->UDP_CSR[0] |= AT91C_UDP_TXPKTRDY;
396 do {
397 csr = pUdp->UDP_CSR[0];
398
399 // Data IN stage has been stopped by a status OUT
400 if (csr & AT91C_UDP_RX_DATA_BK0) {
401 pUdp->UDP_CSR[0] &= ~(AT91C_UDP_RX_DATA_BK0);
402 return;
403 }
404 } while ( !(csr & AT91C_UDP_TXCOMP) );
405
406 } while (length);
407
408 if (pUdp->UDP_CSR[0] & AT91C_UDP_TXCOMP) {
409 pUdp->UDP_CSR[0] &= ~(AT91C_UDP_TXCOMP);
410 while (pUdp->UDP_CSR[0] & AT91C_UDP_TXCOMP);
411 }
412 }
413
414 //*----------------------------------------------------------------------------
415 //* \fn AT91F_USB_SendZlp
416 //* \brief Send zero length packet through the control endpoint
417 //*----------------------------------------------------------------------------
418 void AT91F_USB_SendZlp(AT91PS_UDP pUdp) {
419 pUdp->UDP_CSR[0] |= AT91C_UDP_TXPKTRDY;
420 while ( !(pUdp->UDP_CSR[0] & AT91C_UDP_TXCOMP) );
421 pUdp->UDP_CSR[0] &= ~(AT91C_UDP_TXCOMP);
422 while (pUdp->UDP_CSR[0] & AT91C_UDP_TXCOMP);
423 }
424
425 //*----------------------------------------------------------------------------
426 //* \fn AT91F_USB_SendStall
427 //* \brief Stall the control endpoint
428 //*----------------------------------------------------------------------------
429 void AT91F_USB_SendStall(AT91PS_UDP pUdp) {
430 pUdp->UDP_CSR[0] |= AT91C_UDP_FORCESTALL;
431 while ( !(pUdp->UDP_CSR[0] & AT91C_UDP_ISOERROR) );
432 pUdp->UDP_CSR[0] &= ~(AT91C_UDP_FORCESTALL | AT91C_UDP_ISOERROR);
433 while (pUdp->UDP_CSR[0] & (AT91C_UDP_FORCESTALL | AT91C_UDP_ISOERROR));
434 }
435
436 //*----------------------------------------------------------------------------
437 //* \fn AT91F_CDC_Enumerate
438 //* \brief This function is a callback invoked when a SETUP packet is received
439 //*----------------------------------------------------------------------------
440 void AT91F_CDC_Enumerate() {
441 byte_t bmRequestType, bRequest;
442 uint16_t wValue, wIndex, wLength, wStatus;
443
444 if ( !(pUdp->UDP_CSR[0] & AT91C_UDP_RXSETUP) )
445 return;
446
447 bmRequestType = pUdp->UDP_FDR[0];
448 bRequest = pUdp->UDP_FDR[0];
449 wValue = (pUdp->UDP_FDR[0] & 0xFF);
450 wValue |= (pUdp->UDP_FDR[0] << 8);
451 wIndex = (pUdp->UDP_FDR[0] & 0xFF);
452 wIndex |= (pUdp->UDP_FDR[0] << 8);
453 wLength = (pUdp->UDP_FDR[0] & 0xFF);
454 wLength |= (pUdp->UDP_FDR[0] << 8);
455
456 if (bmRequestType & 0x80) {
457 pUdp->UDP_CSR[0] |= AT91C_UDP_DIR;
458 while ( !(pUdp->UDP_CSR[0] & AT91C_UDP_DIR) );
459 }
460 pUdp->UDP_CSR[0] &= ~AT91C_UDP_RXSETUP;
461 while ( (pUdp->UDP_CSR[0] & AT91C_UDP_RXSETUP) );
462
463 // Handle supported standard device request Cf Table 9-3 in USB specification Rev 1.1
464 switch ((bRequest << 8) | bmRequestType) {
465 case STD_GET_DESCRIPTOR:
466 if (wValue == 0x100) // Return Device Descriptor
467 AT91F_USB_SendData(pUdp, devDescriptor, MIN(sizeof(devDescriptor), wLength));
468 else if (wValue == 0x200) // Return Configuration Descriptor
469 AT91F_USB_SendData(pUdp, cfgDescriptor, MIN(sizeof(cfgDescriptor), wLength));
470 else if ((wValue & 0x300) == 0x300) // Return String Descriptor
471 AT91F_USB_SendData(pUdp, strDescriptor, MIN(sizeof(strDescriptor), wLength));
472 else
473 AT91F_USB_SendStall(pUdp);
474 break;
475 case STD_SET_ADDRESS:
476 AT91F_USB_SendZlp(pUdp);
477 pUdp->UDP_FADDR = (AT91C_UDP_FEN | wValue);
478 pUdp->UDP_GLBSTATE = (wValue) ? AT91C_UDP_FADDEN : 0;
479 break;
480 case STD_SET_CONFIGURATION:
481 btConfiguration = wValue;
482 AT91F_USB_SendZlp(pUdp);
483 pUdp->UDP_GLBSTATE = (wValue) ? AT91C_UDP_CONFG : AT91C_UDP_FADDEN;
484 pUdp->UDP_CSR[1] = (wValue) ? (AT91C_UDP_EPEDS | AT91C_UDP_EPTYPE_BULK_OUT) : 0;
485 pUdp->UDP_CSR[2] = (wValue) ? (AT91C_UDP_EPEDS | AT91C_UDP_EPTYPE_BULK_IN) : 0;
486 pUdp->UDP_CSR[3] = (wValue) ? (AT91C_UDP_EPEDS | AT91C_UDP_EPTYPE_INT_IN) : 0;
487 break;
488 case STD_GET_CONFIGURATION:
489 AT91F_USB_SendData(pUdp, (char *) &(btConfiguration), sizeof(btConfiguration));
490 break;
491 case STD_GET_STATUS_ZERO:
492 wStatus = 0;
493 AT91F_USB_SendData(pUdp, (char *) &wStatus, sizeof(wStatus));
494 break;
495 case STD_GET_STATUS_INTERFACE:
496 wStatus = 0;
497 AT91F_USB_SendData(pUdp, (char *) &wStatus, sizeof(wStatus));
498 break;
499 case STD_GET_STATUS_ENDPOINT:
500 wStatus = 0;
501 wIndex &= 0x0F;
502 if ((pUdp->UDP_GLBSTATE & AT91C_UDP_CONFG) && (wIndex <= 3)) {
503 wStatus = (pUdp->UDP_CSR[wIndex] & AT91C_UDP_EPEDS) ? 0 : 1;
504 AT91F_USB_SendData(pUdp, (char *) &wStatus, sizeof(wStatus));
505 }
506 else if ((pUdp->UDP_GLBSTATE & AT91C_UDP_FADDEN) && (wIndex == 0)) {
507 wStatus = (pUdp->UDP_CSR[wIndex] & AT91C_UDP_EPEDS) ? 0 : 1;
508 AT91F_USB_SendData(pUdp, (char *) &wStatus, sizeof(wStatus));
509 }
510 else
511 AT91F_USB_SendStall(pUdp);
512 break;
513 case STD_SET_FEATURE_ZERO:
514 AT91F_USB_SendStall(pUdp);
515 break;
516 case STD_SET_FEATURE_INTERFACE:
517 AT91F_USB_SendZlp(pUdp);
518 break;
519 case STD_SET_FEATURE_ENDPOINT:
520 wIndex &= 0x0F;
521 if ((wValue == 0) && wIndex && (wIndex <= 3)) {
522 pUdp->UDP_CSR[wIndex] = 0;
523 AT91F_USB_SendZlp(pUdp);
524 }
525 else
526 AT91F_USB_SendStall(pUdp);
527 break;
528 case STD_CLEAR_FEATURE_ZERO:
529 AT91F_USB_SendStall(pUdp);
530 break;
531 case STD_CLEAR_FEATURE_INTERFACE:
532 AT91F_USB_SendZlp(pUdp);
533 break;
534 case STD_CLEAR_FEATURE_ENDPOINT:
535 wIndex &= 0x0F;
536 if ((wValue == 0) && wIndex && (wIndex <= 3)) {
537 if (wIndex == 1)
538 pUdp->UDP_CSR[1] = (AT91C_UDP_EPEDS | AT91C_UDP_EPTYPE_BULK_OUT);
539 else if (wIndex == 2)
540 pUdp->UDP_CSR[2] = (AT91C_UDP_EPEDS | AT91C_UDP_EPTYPE_BULK_IN);
541 else if (wIndex == 3)
542 pUdp->UDP_CSR[3] = (AT91C_UDP_EPEDS | AT91C_UDP_EPTYPE_ISO_IN);
543 AT91F_USB_SendZlp(pUdp);
544 }
545 else
546 AT91F_USB_SendStall(pUdp);
547 break;
548
549 // handle CDC class requests
550 case SET_LINE_CODING:
551 while ( !(pUdp->UDP_CSR[0] & AT91C_UDP_RX_DATA_BK0) );
552 pUdp->UDP_CSR[0] &= ~(AT91C_UDP_RX_DATA_BK0);
553 AT91F_USB_SendZlp(pUdp);
554 break;
555 case GET_LINE_CODING:
556 AT91F_USB_SendData(pUdp, (char *) &line, MIN(sizeof(line), wLength));
557 break;
558 case SET_CONTROL_LINE_STATE:
559 btConnection = wValue;
560 AT91F_USB_SendZlp(pUdp);
561 break;
562 default:
563 AT91F_USB_SendStall(pUdp);
564 break;
565 }
566 }
Impressum, Datenschutz