2 * at91sam7s USB CDC device implementation
4 * Copyright (c) 2012, Roel Verdult
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.
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.
29 * based on the "Basic USB Example" from ATMEL (doc6123.pdf)
36 #include "config_gpio.h"
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
45 const char devDescriptor
[] = {
46 /* Device descriptor */
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
64 const char cfgDescriptor
[] = {
65 /* ============== CONFIGURATION 1 =========== */
66 /* Configuration 1 descriptor */
68 0x02, // CbDescriptorType
69 0x43, // CwTotalLength 2 EP + Control
71 0x02, // CbNumInterfaces
72 0x01, // CbConfigurationValue
73 0x00, // CiConfiguration
74 0xC0, // CbmAttributes 0xA0
77 /* Communication Class Interface Descriptor Requirement */
79 0x04, // bDescriptorType
80 0x00, // bInterfaceNumber
81 0x00, // bAlternateSetting
82 0x01, // bNumEndpoints
83 0x02, // bInterfaceClass
84 0x02, // bInterfaceSubclass
85 0x00, // bInterfaceProtocol
88 /* Header Functional Descriptor */
89 0x05, // bFunction Length
90 0x24, // bDescriptor type: CS_INTERFACE
91 0x00, // bDescriptor subtype: Header Func Desc
95 /* ACM Functional Descriptor */
96 0x04, // bFunctionLength
97 0x24, // bDescriptor Type: CS_INTERFACE
98 0x02, // bDescriptor Subtype: ACM Func Desc
99 0x00, // bmCapabilities
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
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
115 /* Endpoint 1 descriptor */
117 0x05, // bDescriptorType
118 0x83, // bEndpointAddress, Endpoint 03 - IN
119 0x03, // bmAttributes INT
120 0x08, // wMaxPacketSize
124 /* Data Class Interface Descriptor Requirement */
126 0x04, // bDescriptorType
127 0x01, // bInterfaceNumber
128 0x00, // bAlternateSetting
129 0x02, // bNumEndpoints
130 0x0A, // bInterfaceClass
131 0x00, // bInterfaceSubclass
132 0x00, // bInterfaceProtocol
135 /* First alternate setting */
136 /* Endpoint 1 descriptor */
138 0x05, // bDescriptorType
139 0x01, // bEndpointAddress, Endpoint 01 - OUT
140 0x02, // bmAttributes BULK
141 AT91C_EP_OUT_SIZE
, // wMaxPacketSize
145 /* Endpoint 2 descriptor */
147 0x05, // bDescriptorType
148 0x82, // bEndpointAddress, Endpoint 02 - IN
149 0x02, // bmAttributes BULK
150 AT91C_EP_IN_SIZE
, // wMaxPacketSize
155 const char strDescriptor
[] = {
157 0x03, // Type is string
172 // Bitmap for all status bits in CSR.
173 #define REG_NO_EFFECT_1_ALL AT91C_UDP_RX_DATA_BK0 | AT91C_UDP_RX_DATA_BK1 \
174 |AT91C_UDP_STALLSENT | AT91C_UDP_RXSETUP \
177 // Clear flags in the UDP_CSR register and waits for synchronization
178 #define UDP_CLEAR_EP_FLAGS(endpoint, flags) { \
179 volatile unsigned int reg; \
180 reg = pUdp->UDP_CSR[(endpoint)]; \
181 reg |= REG_NO_EFFECT_1_ALL; \
183 pUdp->UDP_CSR[(endpoint)] = reg; \
184 while ( (pUdp->UDP_CSR[(endpoint)] & (flags)) == (flags)); \
187 // reset flags in the UDP_CSR register and waits for synchronization
188 #define UDP_SET_EP_FLAGS(endpoint, flags) { \
189 volatile unsigned int reg; \
190 reg = pUdp->UDP_CSR[(endpoint)]; \
191 reg |= REG_NO_EFFECT_1_ALL; \
193 pUdp->UDP_CSR[(endpoint)] = reg; \
194 while ( ( pUdp->UDP_CSR[(endpoint)] & (flags)) != (flags)); \
198 /* USB standard request code */
199 #define STD_GET_STATUS_ZERO 0x0080
200 #define STD_GET_STATUS_INTERFACE 0x0081
201 #define STD_GET_STATUS_ENDPOINT 0x0082
203 #define STD_CLEAR_FEATURE_ZERO 0x0100
204 #define STD_CLEAR_FEATURE_INTERFACE 0x0101
205 #define STD_CLEAR_FEATURE_ENDPOINT 0x0102
207 #define STD_SET_FEATURE_ZERO 0x0300
208 #define STD_SET_FEATURE_INTERFACE 0x0301
209 #define STD_SET_FEATURE_ENDPOINT 0x0302
211 #define STD_SET_ADDRESS 0x0500
212 #define STD_GET_DESCRIPTOR 0x0680
213 #define STD_SET_DESCRIPTOR 0x0700
214 #define STD_GET_CONFIGURATION 0x0880
215 #define STD_SET_CONFIGURATION 0x0900
216 #define STD_GET_INTERFACE 0x0A81
217 #define STD_SET_INTERFACE 0x0B01
218 #define STD_SYNCH_FRAME 0x0C82
220 /* CDC Class Specific Request Code */
221 #define GET_LINE_CODING 0x21A1
222 #define SET_LINE_CODING 0x2021
223 #define SET_CONTROL_LINE_STATE 0x2221
226 unsigned int dwDTERRate
;
230 } AT91S_CDC_LINE_CODING
, *AT91PS_CDC_LINE_CODING
;
232 AT91S_CDC_LINE_CODING line
= {
238 void AT91F_CDC_Enumerate();
240 AT91PS_UDP pUdp
= AT91C_BASE_UDP
;
241 byte_t btConfiguration
= 0;
242 byte_t btConnection
= 0;
243 byte_t btReceiveBank
= AT91C_UDP_RX_DATA_BK0
;
245 //*----------------------------------------------------------------------------
247 //* \brief This function deactivates the USB device
248 //*----------------------------------------------------------------------------
250 // Disconnect the USB device
251 AT91C_BASE_PIOA
->PIO_ODR
= GPIO_USB_PU
;
253 // Clear all lingering interrupts
254 if(pUdp
->UDP_ISR
& AT91C_UDP_ENDBUSRES
) {
255 pUdp
->UDP_ICR
= AT91C_UDP_ENDBUSRES
;
259 //*----------------------------------------------------------------------------
261 //* \brief This function Activates the USB device
262 //*----------------------------------------------------------------------------
264 // Set the PLL USB Divider
265 AT91C_BASE_CKGR
->CKGR_PLLR
|= AT91C_CKGR_USBDIV_1
;
267 // Specific Chip USB Initialisation
268 // Enables the 48MHz USB clock UDPCK and System Peripheral USB Clock
269 AT91C_BASE_PMC
->PMC_SCER
= AT91C_PMC_UDP
;
270 AT91C_BASE_PMC
->PMC_PCER
= (1 << AT91C_ID_UDP
);
272 // Enable UDP PullUp (USB_DP_PUP) : enable & Clear of the corresponding PIO
273 // Set in PIO mode and Configure in Output
274 AT91C_BASE_PIOA
->PIO_PER
= GPIO_USB_PU
; // Set in PIO mode
275 AT91C_BASE_PIOA
->PIO_OER
= GPIO_USB_PU
; // Configure as Output
277 // Clear for set the Pullup resistor
278 AT91C_BASE_PIOA
->PIO_CODR
= GPIO_USB_PU
;
280 // Disconnect and reconnect USB controller for 100ms
283 // Wait for a short while
284 for (volatile size_t i
=0; i
<0x100000; i
++);
287 // Reconnect USB reconnect
288 AT91C_BASE_PIOA
->PIO_SODR
= GPIO_USB_PU
;
289 AT91C_BASE_PIOA
->PIO_OER
= GPIO_USB_PU
;
292 //*----------------------------------------------------------------------------
294 //* \brief Test if the device is configured and handle enumeration
295 //*----------------------------------------------------------------------------
297 AT91_REG isr
= pUdp
->UDP_ISR
;
299 if (isr
& AT91C_UDP_ENDBUSRES
) {
300 pUdp
->UDP_ICR
= AT91C_UDP_ENDBUSRES
;
301 // reset all endpoints
302 pUdp
->UDP_RSTEP
= (unsigned int)-1;
304 // Enable the function
305 pUdp
->UDP_FADDR
= AT91C_UDP_FEN
;
306 // Configure endpoint 0
307 pUdp
->UDP_CSR
[0] = (AT91C_UDP_EPEDS
| AT91C_UDP_EPTYPE_CTRL
);
309 else if (isr
& AT91C_UDP_EPINT0
) {
310 pUdp
->UDP_ICR
= AT91C_UDP_EPINT0
;
311 AT91F_CDC_Enumerate();
313 return (btConfiguration
) ? true : false;
319 if (!usb_check()) return false;
320 return (pUdp
->UDP_CSR
[AT91C_EP_OUT
] & btReceiveBank
);
324 In github PR #129, some users appears to get a false positive from
325 usb_poll, which returns true, but the usb_read operation
327 This check is basically the same as above, but also checks
328 that the length available to read is non-zero, thus hopefully fixes the
331 bool usb_poll_validate_length()
333 if (!usb_check()) return false;
334 if (!(pUdp
->UDP_CSR
[AT91C_EP_OUT
] & btReceiveBank
)) return false;
335 return (pUdp
->UDP_CSR
[AT91C_EP_OUT
] >> 16) > 0;
338 //*----------------------------------------------------------------------------
340 //* \brief Read available data from Endpoint OUT
341 //*----------------------------------------------------------------------------
342 uint32_t usb_read(byte_t
* data
, size_t len
) {
343 byte_t bank
= btReceiveBank
;
344 uint32_t packetSize
, nbBytesRcv
= 0;
345 uint32_t time_out
= 0;
348 if (!usb_check()) break;
350 if ( pUdp
->UDP_CSR
[AT91C_EP_OUT
] & bank
) {
351 packetSize
= MIN(pUdp
->UDP_CSR
[AT91C_EP_OUT
] >> 16, len
);
354 data
[nbBytesRcv
++] = pUdp
->UDP_FDR
[AT91C_EP_OUT
];
357 UDP_CLEAR_EP_FLAGS(AT91C_EP_OUT
, bank
)
358 //pUdp->UDP_CSR[AT91C_EP_OUT] &= ~(bank);
360 if (bank
== AT91C_UDP_RX_DATA_BK0
)
361 bank
= AT91C_UDP_RX_DATA_BK1
;
363 bank
= AT91C_UDP_RX_DATA_BK0
;
365 if (time_out
++ == 0x1fff) break;
368 btReceiveBank
= bank
;
372 //*----------------------------------------------------------------------------
374 //* \brief Send through endpoint 2
375 //*----------------------------------------------------------------------------
376 uint32_t usb_write(const byte_t
* data
, const size_t len
) {
380 if (!length
) return 0;
381 if (!usb_check()) return 0;
383 // Send the first packet
384 cpt
= MIN(length
, AT91C_EP_IN_SIZE
-1);
386 while (cpt
--) pUdp
->UDP_FDR
[AT91C_EP_IN
] = *data
++;
388 UDP_SET_EP_FLAGS(AT91C_EP_IN
, AT91C_UDP_TXPKTRDY
)
389 //pUdp->UDP_CSR[AT91C_EP_IN] |= AT91C_UDP_TXPKTRDY;
392 // Fill the second bank
393 cpt
= MIN(length
, AT91C_EP_IN_SIZE
-1);
395 while (cpt
--) pUdp
->UDP_FDR
[AT91C_EP_IN
] = *data
++;
396 // Wait for the first bank to be sent
397 while (!(pUdp
->UDP_CSR
[AT91C_EP_IN
] & AT91C_UDP_TXCOMP
)) {
398 if (!usb_check()) return length
;
401 UDP_CLEAR_EP_FLAGS(AT91C_EP_IN
, AT91C_UDP_TXCOMP
)
402 //pUdp->UDP_CSR[AT91C_EP_IN] &= ~(AT91C_UDP_TXCOMP);
403 //while (pUdp->UDP_CSR[AT91C_EP_IN] & AT91C_UDP_TXCOMP);
405 UDP_SET_EP_FLAGS(AT91C_EP_IN
, AT91C_UDP_TXPKTRDY
)
406 //pUdp->UDP_CSR[AT91C_EP_IN] |= AT91C_UDP_TXPKTRDY;
409 // Wait for the end of transfer
410 while (!(pUdp
->UDP_CSR
[AT91C_EP_IN
] & AT91C_UDP_TXCOMP
)) {
411 if (!usb_check()) return length
;
414 UDP_CLEAR_EP_FLAGS(AT91C_EP_IN
, AT91C_UDP_TXCOMP
)
415 //pUdp->UDP_CSR[AT91C_EP_IN] &= ~(AT91C_UDP_TXCOMP);
416 //while (pUdp->UDP_CSR[AT91C_EP_IN] & AT91C_UDP_TXCOMP);
421 //*----------------------------------------------------------------------------
422 //* \fn AT91F_USB_SendData
423 //* \brief Send Data through the control endpoint
424 //*----------------------------------------------------------------------------
425 unsigned int csrTab
[100] = {0x00};
426 unsigned char csrIdx
= 0;
428 static void AT91F_USB_SendData(AT91PS_UDP pUdp
, const char *pData
, uint32_t length
) {
433 cpt
= MIN(length
, 8);
437 pUdp
->UDP_FDR
[0] = *pData
++;
439 if (pUdp
->UDP_CSR
[0] & AT91C_UDP_TXCOMP
) {
441 UDP_CLEAR_EP_FLAGS(0, AT91C_UDP_TXCOMP
)
442 //pUdp->UDP_CSR[0] &= ~(AT91C_UDP_TXCOMP);
443 //while (pUdp->UDP_CSR[0] & AT91C_UDP_TXCOMP);
446 UDP_SET_EP_FLAGS(0, AT91C_UDP_TXPKTRDY
)
447 // pUdp->UDP_CSR[0] |= AT91C_UDP_TXPKTRDY;
449 csr
= pUdp
->UDP_CSR
[0];
451 // Data IN stage has been stopped by a status OUT
452 if (csr
& AT91C_UDP_RX_DATA_BK0
) {
454 UDP_CLEAR_EP_FLAGS(0, AT91C_UDP_RX_DATA_BK0
)
455 //pUdp->UDP_CSR[0] &= ~(AT91C_UDP_RX_DATA_BK0);
458 } while ( !(csr
& AT91C_UDP_TXCOMP
) );
462 if (pUdp
->UDP_CSR
[0] & AT91C_UDP_TXCOMP
) {
464 UDP_CLEAR_EP_FLAGS(0, AT91C_UDP_TXCOMP
)
465 //pUdp->UDP_CSR[0] &= ~(AT91C_UDP_TXCOMP);
466 //while (pUdp->UDP_CSR[0] & AT91C_UDP_TXCOMP);
470 //*----------------------------------------------------------------------------
471 //* \fn AT91F_USB_SendZlp
472 //* \brief Send zero length packet through the control endpoint
473 //*----------------------------------------------------------------------------
474 void AT91F_USB_SendZlp(AT91PS_UDP pUdp
) {
476 UDP_SET_EP_FLAGS(0, AT91C_UDP_TXPKTRDY
)
477 //pUdp->UDP_CSR[0] |= AT91C_UDP_TXPKTRDY;
479 while ( !(pUdp
->UDP_CSR
[0] & AT91C_UDP_TXCOMP
) );
481 UDP_CLEAR_EP_FLAGS(0, AT91C_UDP_TXCOMP
)
482 //pUdp->UDP_CSR[0] &= ~(AT91C_UDP_TXCOMP);
483 //while (pUdp->UDP_CSR[0] & AT91C_UDP_TXCOMP);
486 //*----------------------------------------------------------------------------
487 //* \fn AT91F_USB_SendStall
488 //* \brief Stall the control endpoint
489 //*----------------------------------------------------------------------------
490 void AT91F_USB_SendStall(AT91PS_UDP pUdp
) {
491 pUdp
->UDP_CSR
[0] |= AT91C_UDP_FORCESTALL
;
492 while ( !(pUdp
->UDP_CSR
[0] & AT91C_UDP_ISOERROR
) );
494 pUdp
->UDP_CSR
[0] &= ~(AT91C_UDP_FORCESTALL
| AT91C_UDP_ISOERROR
);
495 while (pUdp
->UDP_CSR
[0] & (AT91C_UDP_FORCESTALL
| AT91C_UDP_ISOERROR
));
498 //*----------------------------------------------------------------------------
499 //* \fn AT91F_CDC_Enumerate
500 //* \brief This function is a callback invoked when a SETUP packet is received
501 //*----------------------------------------------------------------------------
502 void AT91F_CDC_Enumerate() {
503 byte_t bmRequestType
, bRequest
;
504 uint16_t wValue
, wIndex
, wLength
, wStatus
;
506 if ( !(pUdp
->UDP_CSR
[0] & AT91C_UDP_RXSETUP
) )
509 bmRequestType
= pUdp
->UDP_FDR
[0];
510 bRequest
= pUdp
->UDP_FDR
[0];
511 wValue
= (pUdp
->UDP_FDR
[0] & 0xFF);
512 wValue
|= (pUdp
->UDP_FDR
[0] << 8);
513 wIndex
= (pUdp
->UDP_FDR
[0] & 0xFF);
514 wIndex
|= (pUdp
->UDP_FDR
[0] << 8);
515 wLength
= (pUdp
->UDP_FDR
[0] & 0xFF);
516 wLength
|= (pUdp
->UDP_FDR
[0] << 8);
518 if (bmRequestType
& 0x80) {
520 UDP_SET_EP_FLAGS(0, AT91C_UDP_DIR
)
521 //pUdp->UDP_CSR[0] |= AT91C_UDP_DIR;
522 //while ( !(pUdp->UDP_CSR[0] & AT91C_UDP_DIR) );
525 UDP_CLEAR_EP_FLAGS(0, AT91C_UDP_RXSETUP
)
526 //pUdp->UDP_CSR[0] &= ~AT91C_UDP_RXSETUP;
527 //while ( (pUdp->UDP_CSR[0] & AT91C_UDP_RXSETUP) );
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
& 0x300) == 0x300) // Return String Descriptor
537 AT91F_USB_SendData(pUdp
, strDescriptor
, MIN(sizeof(strDescriptor
), wLength
));
539 AT91F_USB_SendStall(pUdp
);
541 case STD_SET_ADDRESS
:
542 AT91F_USB_SendZlp(pUdp
);
543 pUdp
->UDP_FADDR
= (AT91C_UDP_FEN
| wValue
);
544 pUdp
->UDP_GLBSTATE
= (wValue
) ? AT91C_UDP_FADDEN
: 0;
546 case STD_SET_CONFIGURATION
:
547 btConfiguration
= wValue
;
548 AT91F_USB_SendZlp(pUdp
);
549 pUdp
->UDP_GLBSTATE
= (wValue
) ? AT91C_UDP_CONFG
: AT91C_UDP_FADDEN
;
550 pUdp
->UDP_CSR
[1] = (wValue
) ? (AT91C_UDP_EPEDS
| AT91C_UDP_EPTYPE_BULK_OUT
) : 0;
551 pUdp
->UDP_CSR
[2] = (wValue
) ? (AT91C_UDP_EPEDS
| AT91C_UDP_EPTYPE_BULK_IN
) : 0;
552 pUdp
->UDP_CSR
[3] = (wValue
) ? (AT91C_UDP_EPEDS
| AT91C_UDP_EPTYPE_INT_IN
) : 0;
554 case STD_GET_CONFIGURATION
:
555 AT91F_USB_SendData(pUdp
, (char *) &(btConfiguration
), sizeof(btConfiguration
));
557 case STD_GET_STATUS_ZERO
:
559 AT91F_USB_SendData(pUdp
, (char *) &wStatus
, sizeof(wStatus
));
561 case STD_GET_STATUS_INTERFACE
:
563 AT91F_USB_SendData(pUdp
, (char *) &wStatus
, sizeof(wStatus
));
565 case STD_GET_STATUS_ENDPOINT
:
568 if ((pUdp
->UDP_GLBSTATE
& AT91C_UDP_CONFG
) && (wIndex
<= 3)) {
569 wStatus
= (pUdp
->UDP_CSR
[wIndex
] & AT91C_UDP_EPEDS
) ? 0 : 1;
570 AT91F_USB_SendData(pUdp
, (char *) &wStatus
, sizeof(wStatus
));
572 else if ((pUdp
->UDP_GLBSTATE
& AT91C_UDP_FADDEN
) && (wIndex
== 0)) {
573 wStatus
= (pUdp
->UDP_CSR
[wIndex
] & AT91C_UDP_EPEDS
) ? 0 : 1;
574 AT91F_USB_SendData(pUdp
, (char *) &wStatus
, sizeof(wStatus
));
577 AT91F_USB_SendStall(pUdp
);
579 case STD_SET_FEATURE_ZERO
:
580 AT91F_USB_SendStall(pUdp
);
582 case STD_SET_FEATURE_INTERFACE
:
583 AT91F_USB_SendZlp(pUdp
);
585 case STD_SET_FEATURE_ENDPOINT
:
587 if ((wValue
== 0) && wIndex
&& (wIndex
<= 3)) {
588 pUdp
->UDP_CSR
[wIndex
] = 0;
589 AT91F_USB_SendZlp(pUdp
);
592 AT91F_USB_SendStall(pUdp
);
594 case STD_CLEAR_FEATURE_ZERO
:
595 AT91F_USB_SendStall(pUdp
);
597 case STD_CLEAR_FEATURE_INTERFACE
:
598 AT91F_USB_SendZlp(pUdp
);
600 case STD_CLEAR_FEATURE_ENDPOINT
:
602 if ((wValue
== 0) && wIndex
&& (wIndex
<= 3)) {
604 pUdp
->UDP_CSR
[1] = (AT91C_UDP_EPEDS
| AT91C_UDP_EPTYPE_BULK_OUT
);
605 else if (wIndex
== 2)
606 pUdp
->UDP_CSR
[2] = (AT91C_UDP_EPEDS
| AT91C_UDP_EPTYPE_BULK_IN
);
607 else if (wIndex
== 3)
608 pUdp
->UDP_CSR
[3] = (AT91C_UDP_EPEDS
| AT91C_UDP_EPTYPE_ISO_IN
);
609 AT91F_USB_SendZlp(pUdp
);
612 AT91F_USB_SendStall(pUdp
);
615 // handle CDC class requests
616 case SET_LINE_CODING
:
617 while ( !(pUdp
->UDP_CSR
[0] & AT91C_UDP_RX_DATA_BK0
) );
618 UDP_CLEAR_EP_FLAGS(0, AT91C_UDP_RX_DATA_BK0
)
619 //pUdp->UDP_CSR[0] &= ~(AT91C_UDP_RX_DATA_BK0);
620 AT91F_USB_SendZlp(pUdp
);
622 case GET_LINE_CODING
:
623 AT91F_USB_SendData(pUdp
, (char *) &line
, MIN(sizeof(line
), wLength
));
625 case SET_CONTROL_LINE_STATE
:
626 btConnection
= wValue
;
627 AT91F_USB_SendZlp(pUdp
);
630 AT91F_USB_SendStall(pUdp
);